mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
First attempt at a remote Store API - AVM store impl
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8932 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Remote AVM Store</shortname>
|
||||||
|
<description>Remote service mirroring the Store interface - to an AVM store</description>
|
||||||
|
<url>/remotestore/{method}/{path}</url>
|
||||||
|
<authentication>guest</authentication>
|
||||||
|
<format default="">argument</format>
|
||||||
|
</webscript>
|
@@ -0,0 +1,7 @@
|
|||||||
|
<webscript>
|
||||||
|
<shortname>Remote AVM Store</shortname>
|
||||||
|
<description>Remote service mirroring the Store interface - to an AVM store</description>
|
||||||
|
<url>/remotestore/{method}/{path}</url>
|
||||||
|
<authentication>guest</authentication>
|
||||||
|
<format default="">argument</format>
|
||||||
|
</webscript>
|
@@ -213,4 +213,19 @@
|
|||||||
<property name="mimetypeService" ref="MimetypeService" />
|
<property name="mimetypeService" ref="MimetypeService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!-- Remote Store service - AVM -->
|
||||||
|
<bean id="webscript.org.alfresco.repository.store.remoteavm.get" class="org.alfresco.repo.web.scripts.bean.AVMRemoteStore" parent="webscript">
|
||||||
|
<property name="mimetypeService" ref="MimetypeService" />
|
||||||
|
<property name="avmService" ref="AVMService" />
|
||||||
|
<property name="rootPath"><value>site-data</value></property>
|
||||||
|
<property name="store"><value>sitestore</value></property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="webscript.org.alfresco.repository.store.remoteavm.post" class="org.alfresco.repo.web.scripts.bean.AVMRemoteStore" parent="webscript">
|
||||||
|
<property name="mimetypeService" ref="MimetypeService" />
|
||||||
|
<property name="avmService" ref="AVMService" />
|
||||||
|
<property name="rootPath"><value>site-data</value></property>
|
||||||
|
<property name="store"><value>sitestore</value></property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.web.scripts.bean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
|
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||||
|
import org.alfresco.service.cmr.avm.AVMService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
|
import org.alfresco.web.scripts.WebScriptResponse;
|
||||||
|
import org.alfresco.web.scripts.servlet.WebScriptServletResponse;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AVM Remote Store service.
|
||||||
|
*
|
||||||
|
* @see BaseRemoteStore for API methods.
|
||||||
|
*
|
||||||
|
* @author Kevin Roast
|
||||||
|
*/
|
||||||
|
public class AVMRemoteStore extends BaseRemoteStore
|
||||||
|
{
|
||||||
|
private static final Log logger = LogFactory.getLog(AVMRemoteStore.class);
|
||||||
|
|
||||||
|
private String rootPath;
|
||||||
|
private AVMService avmService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param rootPath the root path under which to process store requests
|
||||||
|
*/
|
||||||
|
public void setRootPath(String rootPath)
|
||||||
|
{
|
||||||
|
this.rootPath = rootPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param avmService the AVMService to set
|
||||||
|
*/
|
||||||
|
public void setAvmService(AVMService avmService)
|
||||||
|
{
|
||||||
|
this.avmService = avmService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last modified timestamp for the document.
|
||||||
|
*
|
||||||
|
* @param path document path to an existing document
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void lastModified(WebScriptResponse res, String path)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
String avmPath = buildAVMPath(path);
|
||||||
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
|
if (desc == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Unable to locate AVM file: " + avmPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Writer out = res.getWriter();
|
||||||
|
out.write(Long.toString(desc.getModDate()));
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#getDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void getDocument(WebScriptResponse res, String path) throws IOException
|
||||||
|
{
|
||||||
|
String avmPath = buildAVMPath(path);
|
||||||
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
|
if (desc == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Unable to locate file: " + avmPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentReader reader = this.avmService.getContentReader(-1, avmPath);
|
||||||
|
if (reader == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("No content found for AVM file: " + avmPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// establish mimetype
|
||||||
|
String mimetype = reader.getMimetype();
|
||||||
|
if (mimetype == null || mimetype.length() == 0)
|
||||||
|
{
|
||||||
|
mimetype = MimetypeMap.MIMETYPE_BINARY;
|
||||||
|
int extIndex = path.lastIndexOf('.');
|
||||||
|
if (extIndex != -1)
|
||||||
|
{
|
||||||
|
String ext = path.substring(extIndex + 1);
|
||||||
|
String mt = this.mimetypeService.getMimetypesByExtension().get(ext);
|
||||||
|
if (mt != null)
|
||||||
|
{
|
||||||
|
mimetype = mt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set mimetype for the content and the character encoding + length for the stream
|
||||||
|
WebScriptServletResponse httpRes = (WebScriptServletResponse)res;
|
||||||
|
httpRes.setContentType(mimetype);
|
||||||
|
httpRes.getHttpServletResponse().setCharacterEncoding(reader.getEncoding());
|
||||||
|
httpRes.getHttpServletResponse().setDateHeader("Last-Modified", desc.getModDate());
|
||||||
|
httpRes.setHeader("Content-Length", Long.toString(reader.getSize()));
|
||||||
|
|
||||||
|
// get the content and stream directly to the response output stream
|
||||||
|
// assuming the repository is capable of streaming in chunks, this should allow large files
|
||||||
|
// to be streamed directly to the browser response stream.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reader.getContent(res.getOutputStream());
|
||||||
|
}
|
||||||
|
catch (SocketException e1)
|
||||||
|
{
|
||||||
|
// the client cut the connection - our mission was accomplished apart from a little error message
|
||||||
|
if (logger.isInfoEnabled())
|
||||||
|
logger.info("Client aborted stream read:\n\tnode: " + avmPath + "\n\tcontent: " + reader);
|
||||||
|
}
|
||||||
|
catch (ContentIOException e2)
|
||||||
|
{
|
||||||
|
if (logger.isInfoEnabled())
|
||||||
|
logger.info("Client aborted stream read:\n\tnode: " + avmPath + "\n\tcontent: " + reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#hasDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void hasDocument(WebScriptResponse res, String path) throws IOException
|
||||||
|
{
|
||||||
|
String avmPath = buildAVMPath(path);
|
||||||
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
|
|
||||||
|
Writer out = res.getWriter();
|
||||||
|
out.write(Boolean.toString(desc != null));
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#createDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.io.InputStream)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void createDocument(WebScriptResponse res, String path, InputStream content)
|
||||||
|
{
|
||||||
|
String avmPath = buildAVMPath(path);
|
||||||
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
|
if (desc != null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Unable to create, file already exists: " + avmPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = AVMNodeConverter.SplitBase(avmPath);
|
||||||
|
this.avmService.createFile(parts[0], parts[1], content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.web.scripts.bean.BaseRemoteStore#updateDocument(org.alfresco.web.scripts.WebScriptResponse, java.lang.String, java.io.InputStream)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void updateDocument(WebScriptResponse res, String path, InputStream content)
|
||||||
|
{
|
||||||
|
String avmPath = buildAVMPath(path);
|
||||||
|
AVMNodeDescriptor desc = this.avmService.lookup(-1, avmPath);
|
||||||
|
if (desc == null)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Unable to locate file for update: " + avmPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentWriter writer = this.avmService.getContentWriter(avmPath);
|
||||||
|
writer.putContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param path root path relative
|
||||||
|
*
|
||||||
|
* @return full AVM path to document including store and root path components
|
||||||
|
*/
|
||||||
|
private String buildAVMPath(String path)
|
||||||
|
{
|
||||||
|
return this.store + ":/" + this.rootPath + "/" + path;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,254 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.web.scripts.bean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.web.scripts.AbstractWebScript;
|
||||||
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
|
import org.alfresco.web.scripts.WebScriptRequest;
|
||||||
|
import org.alfresco.web.scripts.WebScriptResponse;
|
||||||
|
import org.alfresco.web.scripts.servlet.WebScriptServletRequest;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote Store service.
|
||||||
|
*
|
||||||
|
* Responsible for providing remote HTTP based access to a store. Designed to be accessed
|
||||||
|
* from a web-tier application to remotely mirror a WebScript Store instance.
|
||||||
|
*
|
||||||
|
* Request format:
|
||||||
|
*
|
||||||
|
* <servicepath>/<method>/<path>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* /service/store/lastmodified/sites/xyz/pages/page.xml
|
||||||
|
*
|
||||||
|
* where: /service/store -> service path
|
||||||
|
* /lastmodified -> method name
|
||||||
|
* /sites/../page.xml -> document path
|
||||||
|
*
|
||||||
|
* Note: path is relative to the root path as configured for this webscript bean
|
||||||
|
*
|
||||||
|
* For content create and update the request should be POSTed and the content sent as the
|
||||||
|
* payload of the request content.
|
||||||
|
*
|
||||||
|
* Supported method API:
|
||||||
|
* GET lastmodified -> return long timestamp of a document
|
||||||
|
* GET has -> return true/false of existence for a document
|
||||||
|
* GET get -> return document content - in addition the usual HTTP headers for the
|
||||||
|
* character encoding, content type, length and modified date will be supplied
|
||||||
|
* POST create -> create a new document with request content payload
|
||||||
|
* POST update -> update an existing document with request content payload
|
||||||
|
*
|
||||||
|
* @author Kevin Roast
|
||||||
|
*/
|
||||||
|
public abstract class BaseRemoteStore extends AbstractWebScript
|
||||||
|
{
|
||||||
|
private static final Log logger = LogFactory.getLog(BaseRemoteStore.class);
|
||||||
|
|
||||||
|
protected String store;
|
||||||
|
protected ContentService contentService;
|
||||||
|
protected MimetypeService mimetypeService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param store the store name of the store to process document requests against
|
||||||
|
*/
|
||||||
|
public void setStore(String store)
|
||||||
|
{
|
||||||
|
this.store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param contentService the ContentService to set
|
||||||
|
*/
|
||||||
|
public void setContentService(ContentService contentService)
|
||||||
|
{
|
||||||
|
this.contentService = contentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mimetypeService the MimetypeService to set
|
||||||
|
*/
|
||||||
|
public void setMimetypeService(MimetypeService mimetypeService)
|
||||||
|
{
|
||||||
|
this.mimetypeService = mimetypeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the webscript based on the request parameters
|
||||||
|
*/
|
||||||
|
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
|
||||||
|
{
|
||||||
|
// NOTE: This web script must be executed in a HTTP Servlet environment
|
||||||
|
if (!(req instanceof WebScriptServletRequest))
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Remote Store access must be executed in HTTP Servlet environment");
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
|
||||||
|
|
||||||
|
// break down and validate the request - expecting method name and document path
|
||||||
|
String extPath = req.getExtensionPath();
|
||||||
|
String[] extParts = extPath == null ? new String[0] : extPath.split("/");
|
||||||
|
if (extParts.length < 1)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Remote Store expecting method name.");
|
||||||
|
}
|
||||||
|
if (extParts.length < 2)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Remote Store expecting document path.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// build path as a string and as a list of path elements
|
||||||
|
String path = req.getExtensionPath().substring(extParts[0].length() + 1);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Remote store method: " + extParts[0] + " path: " + path);
|
||||||
|
|
||||||
|
// TODO: support storeref name override as argument (i.e. for AVM virtualisation)
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// generate enum from string method name - so we can use a fast switch table lookup
|
||||||
|
APIMethod method = APIMethod.valueOf(extParts[0].toUpperCase());
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case LASTMODIFIED:
|
||||||
|
lastModified(res, path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAS:
|
||||||
|
hasDocument(res, path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GET:
|
||||||
|
getDocument(res, path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CREATE:
|
||||||
|
createDocument(res, path, httpReq.getInputStream());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UPDATE:
|
||||||
|
updateDocument(res, path, httpReq.getInputStream());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException enumErr)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Unknown method specified to remote store API: " + extParts[0]);
|
||||||
|
}
|
||||||
|
catch (IOException ioErr)
|
||||||
|
{
|
||||||
|
throw new WebScriptException("Error during remote store API: " + ioErr.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to break down webscript extension path into path component elements
|
||||||
|
*/
|
||||||
|
protected List<String> getPathParts(String[] extPaths)
|
||||||
|
{
|
||||||
|
List<String> pathParts = new ArrayList<String>(extPaths.length - 1);
|
||||||
|
for (int i=1; i<extPaths.length; i++)
|
||||||
|
{
|
||||||
|
pathParts.add(extPaths[i]);
|
||||||
|
}
|
||||||
|
return pathParts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last modified timestamp for the document.
|
||||||
|
*
|
||||||
|
* @param path document path to an existing document
|
||||||
|
*/
|
||||||
|
protected abstract void lastModified(WebScriptResponse res, String path)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the document exists
|
||||||
|
*
|
||||||
|
* @param path document path
|
||||||
|
* @return true => exists, false => does not exist
|
||||||
|
*/
|
||||||
|
protected abstract void hasDocument(WebScriptResponse res, String path)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a document
|
||||||
|
*
|
||||||
|
* @param path document path
|
||||||
|
* @return input stream onto document
|
||||||
|
*
|
||||||
|
* @throws IOException if the document does not exist in the store
|
||||||
|
*/
|
||||||
|
protected abstract void getDocument(WebScriptResponse res, String path)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a document.
|
||||||
|
*
|
||||||
|
* @param path document path
|
||||||
|
* @param content content of the document to write
|
||||||
|
*
|
||||||
|
* @throws IOException if the document already exists or the create fails
|
||||||
|
*/
|
||||||
|
protected abstract void createDocument(WebScriptResponse res, String path, InputStream content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing document.
|
||||||
|
*
|
||||||
|
* @param path document path
|
||||||
|
* @param content content to update the document with
|
||||||
|
*
|
||||||
|
* @throws IOException if the document does not exist or the update fails
|
||||||
|
*/
|
||||||
|
protected abstract void updateDocument(WebScriptResponse res, String path, InputStream content);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum representing the API method on the Store.
|
||||||
|
*/
|
||||||
|
private enum APIMethod
|
||||||
|
{
|
||||||
|
LASTMODIFIED,
|
||||||
|
HAS,
|
||||||
|
GET,
|
||||||
|
CREATE,
|
||||||
|
UPDATE
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user