blob: b73d12df97d6481068b7f48402f9f7eb4a485364 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.abdera.protocol.server.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.security.auth.Subject;
import org.apache.abdera.Abdera;
import org.apache.abdera.model.Service;
import org.apache.abdera.protocol.Resolver;
import org.apache.abdera.protocol.server.CategoriesInfo;
import org.apache.abdera.protocol.server.CategoryInfo;
import org.apache.abdera.protocol.server.CollectionAdapter;
import org.apache.abdera.protocol.server.CollectionInfo;
import org.apache.abdera.protocol.server.Filter;
import org.apache.abdera.protocol.server.MediaCollectionAdapter;
import org.apache.abdera.protocol.server.Provider;
import org.apache.abdera.protocol.server.ProviderHelper;
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.Transactional;
import org.apache.abdera.protocol.server.WorkspaceInfo;
import org.apache.abdera.protocol.server.WorkspaceManager;
import org.apache.abdera.protocol.server.context.StreamWriterResponseContext;
import org.apache.abdera.util.Constants;
import org.apache.abdera.writer.StreamWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Base Provider implementation that provides the core implementation details
* for all Providers. This class provides the basic request routing logic
*/
public abstract class AbstractProvider
implements Provider {
private final static Log log = LogFactory.getLog(AbstractProvider.class);
protected Abdera abdera;
protected Map<String,String> properties;
protected List<Filter> filters = new ArrayList<Filter>();
public void init(
Abdera abdera,
Map<String, String> properties) {
this.abdera = abdera;
this.properties = properties;
}
public String getProperty(String name) {
return properties.get(name);
}
public String[] getPropertyNames() {
return properties.keySet().toArray(new String[properties.size()]);
}
public Abdera getAbdera() {
return abdera;
}
public Subject resolveSubject(RequestContext request) {
Resolver<Subject> subjectResolver = getSubjectResolver(request);
return subjectResolver != null ?
subjectResolver.resolve(request) : null;
}
public Target resolveTarget(RequestContext request) {
Resolver<Target> targetResolver =
getTargetResolver(request);
return targetResolver != null ?
targetResolver.resolve(request) : null;
}
public String urlFor(
RequestContext request,
Object key,
Object param) {
TargetBuilder tm = getTargetBuilder(request);
return tm != null ? tm.urlFor(request, key, param) : null;
}
protected Resolver<Subject> getSubjectResolver(RequestContext request) {
return new SimpleSubjectResolver();
}
protected abstract TargetBuilder getTargetBuilder(RequestContext request);
protected abstract Resolver<Target> getTargetResolver(RequestContext request);
public ResponseContext process(
RequestContext request) {
Target target = request.getTarget();
if (target == null ||
target.getType() == TargetType.TYPE_NOT_FOUND)
return ProviderHelper.notfound(request);
String method = request.getMethod();
TargetType type = target.getType();
if (type == TargetType.TYPE_SERVICE &&
method.equalsIgnoreCase("GET")) {
return getServiceDocument(request);
}
WorkspaceManager wm = getWorkspaceManager(request);
CollectionAdapter adapter =
wm.getCollectionAdapter(request);
if (adapter == null) {
return ProviderHelper.notfound(
request);
}
Transactional transaction =
adapter instanceof Transactional ?
(Transactional)adapter : null;
ResponseContext response = null;
try {
if (transaction != null) transaction.start(request);
if (type == TargetType.TYPE_CATEGORIES) {
if (method.equalsIgnoreCase("GET"))
response = adapter.getCategories(request);
} else if (type == TargetType.TYPE_COLLECTION) {
if (method.equalsIgnoreCase("GET"))
response = adapter.getFeed(request);
else if (method.equalsIgnoreCase("POST")) {
response = ProviderHelper.isAtom(request) ?
adapter.postEntry(request) :
adapter instanceof MediaCollectionAdapter ?
((MediaCollectionAdapter)adapter).postMedia(request) :
ProviderHelper.notsupported(request);
}
} else if (type == TargetType.TYPE_ENTRY) {
if (method.equalsIgnoreCase("GET"))
response = adapter.getEntry(request);
else if (method.equalsIgnoreCase("PUT"))
response = adapter.putEntry(request);
else if (method.equalsIgnoreCase("DELETE"))
response = adapter.deleteEntry(request);
else if (method.equalsIgnoreCase("HEAD"))
response = adapter.headEntry(request);
else if (method.equalsIgnoreCase("OPTIONS"))
response = adapter.optionsEntry(request);
} else if (type == TargetType.TYPE_MEDIA) {
if (adapter instanceof MediaCollectionAdapter) {
MediaCollectionAdapter mcadapter =
(MediaCollectionAdapter) adapter;
if (method.equalsIgnoreCase("GET"))
response = mcadapter.getMedia(request);
else if (method.equalsIgnoreCase("PUT"))
response = mcadapter.putMedia(request);
else if (method.equalsIgnoreCase("DELETE"))
response = mcadapter.deleteMedia(request);
else if (method.equalsIgnoreCase("HEAD"))
response = mcadapter.headMedia(request);
else if (method.equalsIgnoreCase("OPTIONS"))
response = mcadapter.optionsMedia(request);
} else {
response = ProviderHelper.notsupported(request);
}
} else if (type == TargetType.TYPE_NOT_FOUND) {
response = ProviderHelper.notfound(request);
} else {
response = adapter.extensionRequest(request);
}
if (response == null)
response = ProviderHelper.notsupported(request);
return response;
} catch (Throwable e) {
log.error(e);
if (transaction != null)
transaction.compensate(request,e);
response = ProviderHelper.servererror(request, e);
return response;
} finally {
if (transaction != null)
transaction.end(request, response);
}
}
protected abstract WorkspaceManager getWorkspaceManager(
RequestContext request);
protected Service getServiceElement(RequestContext request) {
Service service = abdera.newService();
for (WorkspaceInfo wi : getWorkspaceManager(request).getWorkspaces(request))
service.addWorkspace(wi.asWorkspaceElement(request));
return service;
}
protected ResponseContext getServiceDocument(
final RequestContext request) {
return
new StreamWriterResponseContext(request.getAbdera()) {
protected void writeTo(
StreamWriter sw)
throws IOException {
sw.startDocument()
.startService();
for (WorkspaceInfo wi : getWorkspaceManager(request).getWorkspaces(request)) {
sw.startWorkspace()
.writeTitle(wi.getTitle(request));
for (CollectionInfo ci : wi.getCollections(request)) {
sw.startCollection(ci.getHref(request))
.writeTitle(ci.getTitle(request))
.writeAccepts(ci.getAccepts(request));
CategoriesInfo[] catinfos = ci.getCategoriesInfo(request);
if (catinfos != null) {
for (CategoriesInfo catinfo : catinfos) {
String cathref = catinfo.getHref(request);
if (cathref != null) {
sw.startCategories()
.writeAttribute("href", request.getTargetBasePath() + cathref)
.endCategories();
} else {
sw.startCategories(
catinfo.isFixed(request),
catinfo.getScheme(request));
for (CategoryInfo cat : catinfo) {
sw.writeCategory(
cat.getTerm(request),
cat.getScheme(request),
cat.getLabel(request));
}
sw.endCategories();
}
}
}
sw.endCollection();
}
sw.endWorkspace();
}
sw.endService()
.endDocument();
}
}
.setStatus(200)
.setContentType(Constants.APP_MEDIA_TYPE);
}
public void setFilters(List<Filter> filters) {
this.filters = filters;
}
public Filter[] getFilters(RequestContext request) {
return filters.toArray(new Filter[filters.size()]);
}
public void addFilter(Filter... filters) {
for (Filter filter : filters)
this.filters.add(filter);
}
}