blob: 9579fa4874e09044e1bd935a18cd3416e1f78293 [file] [log] [blame]
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Authors:
* Florent Guillaume, Nuxeo
* Amelie Avramo, EntropySoft
*/
package org.apache.chemistry.atompub.server;
import java.util.ArrayList;
import java.util.List;
import org.apache.abdera.protocol.Resolver;
import org.apache.abdera.protocol.server.RequestContext;
import org.apache.abdera.protocol.server.ResponseContext;
import org.apache.abdera.protocol.server.Target;
import org.apache.abdera.protocol.server.TargetBuilder;
import org.apache.abdera.protocol.server.TargetType;
import org.apache.abdera.protocol.server.WorkspaceManager;
import org.apache.abdera.protocol.server.impl.AbstractProvider;
import org.apache.abdera.protocol.server.impl.AbstractWorkspaceManager;
import org.apache.abdera.protocol.server.impl.RegexTargetResolver;
import org.apache.abdera.protocol.server.impl.SimpleWorkspaceInfo;
import org.apache.abdera.protocol.server.impl.TemplateTargetBuilder;
import org.apache.abdera.util.Constants;
import org.apache.chemistry.Repository;
import org.apache.chemistry.atompub.AtomPub;
import org.apache.chemistry.atompub.AtomPubCMIS;
import org.apache.chemistry.atompub.URITemplate;
/**
* Abdera provider for the CMIS bindings used by Chemistry.
*/
public class CMISProvider extends AbstractProvider {
protected final Repository repository;
protected final AbstractWorkspaceManager workspaceManager;
protected final TemplateTargetBuilder targetBuilder;
protected final RegexTargetResolver targetResolver;
public CMISProvider(Repository repository) {
this.repository = repository;
targetBuilder = new TemplateTargetBuilder();
targetResolver = new ServletRegexTargetResolver();
// service
targetBuilder.setTemplate(TargetType.TYPE_SERVICE,
"{target_base}/repository");
targetResolver.setPattern("/repository(\\?.*)?",
TargetType.TYPE_SERVICE);
// entry
targetBuilder.setTemplate(TargetType.TYPE_ENTRY,
"{target_base}/{entrytype}/{id}");
targetResolver.setPattern("/object(?:/?)([^/?]*)(\\?.*)?",
TargetType.TYPE_ENTRY, "objectid");
targetResolver.setPattern("/allowableactions/([^/?]+)",
TargetType.TYPE_ENTRY, "objectid");
targetResolver.setPattern("/type/([^/?]+)(\\?.*)?",
TargetType.TYPE_ENTRY, "typeid");
targetResolver.setPattern("/path/([^?]*)(\\?.*)?",
TargetType.TYPE_ENTRY, "path");
// media
targetBuilder.setTemplate(TargetType.TYPE_MEDIA,
"{target_base}/file/{objectid}");
targetResolver.setPattern("/file/([^/?]+)", TargetType.TYPE_MEDIA,
"objectid");
// collection
// global workpace collections
targetBuilder.setTemplate(TargetType.TYPE_COLLECTION,
"{target_base}/{collection}{-prefix|/|id}");
targetResolver.setPattern("/checkedout(\\?.*)?",
TargetType.TYPE_COLLECTION);
targetResolver.setPattern("/unfiled", TargetType.TYPE_COLLECTION);
targetResolver.setPattern("/query(\\?.*)?",
CMISQueryFeed.TARGET_TYPE_CMIS_QUERY);
targetResolver.setPattern("/typechildren(\\?.*)?", //
TargetType.TYPE_COLLECTION);
// per-object collections
targetResolver.setPattern("/parents/([^/?]+)(\\?.*)?",
TargetType.TYPE_COLLECTION, "objectid");
targetResolver.setPattern("/children/([^/?]+)(\\?.*)?",
TargetType.TYPE_COLLECTION, "objectid");
targetResolver.setPattern("/descendants/([^/?]+)(\\?.*)?",
CMISObjectsCollection.TARGET_TYPE_CMIS_DESCENDANTS, "objectid");
targetResolver.setPattern("/foldertree/([^/?]+)(\\?.*)?",
CMISObjectsCollection.TARGET_TYPE_CMIS_FOLDER_TREE, "objectid");
targetResolver.setPattern("/allversions/([^/?]+)(\\?.*)?",
TargetType.TYPE_COLLECTION, "objectid");
targetResolver.setPattern("/relationships/([^/?]+)(\\?.*)?",
TargetType.TYPE_COLLECTION, "objectid");
targetResolver.setPattern("/policies/([^/?]+)(\\?.*)?",
TargetType.TYPE_COLLECTION, "objectid");
targetResolver.setPattern("/typechildren/([^/?]+)(\\?.*)?",
TargetType.TYPE_COLLECTION, "typeid");
targetResolver.setPattern("/typedescendants(\\?.*)?",
TargetType.TYPE_COLLECTION);
targetResolver.setPattern("/typedescendants/([^/?]+)(\\?.*)?",
TargetType.TYPE_COLLECTION, "typeid");
// CMIS workspaces available
SimpleWorkspaceInfo workspaceInfo = new SimpleWorkspaceInfo();
workspaceInfo.setTitle(repository.getInfo().getName());
workspaceInfo.addCollection(new CMISChildrenCollection(
AtomPubCMIS.COL_ROOT,
repository.getInfo().getRootFolderId().getId(), repository));
workspaceInfo.addCollection(new CMISCollectionForOther(
AtomPubCMIS.COL_UNFILED, "unfiled", null, repository));
workspaceInfo.addCollection(new CMISCollectionForOther(
AtomPubCMIS.COL_CHECKED_OUT, "checkedout", null, repository));
workspaceInfo.addCollection(new CMISTypesCollection(
AtomPubCMIS.COL_TYPES, null, repository));
workspaceInfo.addCollection(new CMISQueryFeed(repository));
workspaceManager = new CMISWorkspaceManager(this);
workspaceManager.addWorkspace(workspaceInfo);
}
public Repository getRepository() {
return repository;
}
public List<URITemplate> getURITemplates(RequestContext request) {
String base = request.getBaseUri().toString();
if (base.endsWith("/")) {
base = base.substring(0, base.length() - 1);
}
// add servlet path
base += request.getTargetBasePath().substring(
request.getContextPath().length());
List<URITemplate> list = new ArrayList<URITemplate>(3);
list.add(new URITemplate(AtomPubCMIS.URITMPL_OBJECT_BY_ID,
AtomPub.MEDIA_TYPE_ATOM_ENTRY, addURITemplateParameters(
base + "/object/{id}", //
AtomPubCMIS.PARAM_FILTER,
AtomPubCMIS.PARAM_RENDITION_FILTER,
AtomPubCMIS.PARAM_INCLUDE_RELATIONSHIPS,
AtomPubCMIS.PARAM_INCLUDE_ALLOWABLE_ACTIONS,
AtomPubCMIS.PARAM_INCLUDE_POLICY_IDS,
AtomPubCMIS.PARAM_INCLUDE_ACL)));
list.add(new URITemplate(AtomPubCMIS.URITMPL_OBJECT_BY_PATH,
AtomPub.MEDIA_TYPE_ATOM_ENTRY, addURITemplateParameters(
base + "/object", //
AtomPubCMIS.PARAM_PATH, //
AtomPubCMIS.PARAM_FILTER,
AtomPubCMIS.PARAM_RENDITION_FILTER,
AtomPubCMIS.PARAM_INCLUDE_RELATIONSHIPS,
AtomPubCMIS.PARAM_INCLUDE_ALLOWABLE_ACTIONS,
AtomPubCMIS.PARAM_INCLUDE_POLICY_IDS,
AtomPubCMIS.PARAM_INCLUDE_ACL)));
list.add(new URITemplate(AtomPubCMIS.URITMPL_QUERY, //
AtomPub.MEDIA_TYPE_ATOM_FEED, addURITemplateParameters(
base + "/query",
AtomPubCMIS.PARAM_QUERY, //
AtomPubCMIS.PARAM_SEARCH_ALL_VERSIONS,
AtomPubCMIS.PARAM_MAX_ITEMS,
AtomPubCMIS.PARAM_SKIP_COUNT,
AtomPubCMIS.PARAM_INCLUDE_RELATIONSHIPS,
AtomPubCMIS.PARAM_INCLUDE_ALLOWABLE_ACTIONS)));
list.add(new URITemplate(AtomPubCMIS.URITMPL_TYPE_BY_ID, //
AtomPub.MEDIA_TYPE_ATOM_FEED, //
base + "/type/{id}"));
return list;
}
protected static String addURITemplateParameters(String s, String... params) {
StringBuilder buf = new StringBuilder(s);
for (int i = 0; i < params.length; i++) {
String param = params[i];
buf.append(i == 0 ? '?' : '&');
buf.append(param);
buf.append("={");
buf.append(param);
buf.append('}');
}
return buf.toString();
}
@Override
protected TargetBuilder getTargetBuilder(RequestContext request) {
return targetBuilder;
}
@Override
protected Resolver<Target> getTargetResolver(RequestContext request) {
return targetResolver;
}
@Override
public WorkspaceManager getWorkspaceManager(RequestContext request) {
return workspaceManager;
}
@Override
public ResponseContext getServiceDocument(final RequestContext request) {
CMISServiceResponse response = new CMISServiceResponse(this, request);
response.setStatus(200);
response.setContentType(Constants.APP_MEDIA_TYPE);
return response;
}
}