/**
* Copyright (C) 2010 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xcmis.restatom.collections;
import org.apache.abdera.i18n.iri.IRI;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Person;
import org.apache.abdera.protocol.server.RequestContext;
import org.apache.abdera.protocol.server.ResponseContext;
import org.apache.abdera.protocol.server.TargetType;
import org.apache.abdera.protocol.server.context.ResponseContextException;
import org.xcmis.restatom.AtomCMIS;
import org.xcmis.restatom.AtomUtils;
import org.xcmis.restatom.abdera.TypeDefinitionTypeElement;
import org.xcmis.spi.Connection;
import org.xcmis.spi.ConstraintException;
import org.xcmis.spi.InvalidArgumentException;
import org.xcmis.spi.StorageException;
import org.xcmis.spi.TypeNotFoundException;
import org.xcmis.spi.model.TypeDefinition;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:andrey.parfonov@exoplatform.com">Andrey Parfonov</a>
* @version $Id: CmisTypeCollection.java 47 2010-02-08 22:59:45Z andrew00x $
*/
public abstract class CmisTypeCollection extends AbstractCmisCollection<TypeDefinition>
{
public CmisTypeCollection(Connection connection)
{
super(connection);
}
/**
* {@inheritDoc}
*/
public String getAuthor(RequestContext request) throws ResponseContextException
{
return SYSTEM;
}
/**
* {@inheritDoc}
*/
public TypeDefinition getEntry(String typeId, RequestContext request) throws ResponseContextException
{
try
{
Connection connection = getConnection(request);
TypeDefinition type = connection.getTypeDefinition(typeId);
return type;
}
catch (TypeNotFoundException tne)
{
throw new ResponseContextException(createErrorResponse(tne, 400));
}
catch (Exception t)
{
throw new ResponseContextException(createErrorResponse(t, 500));
}
}
/**
* {@inheritDoc}
*/
public String getId(TypeDefinition entry) throws ResponseContextException
{
return entry.getId();
}
/**
* {@inheritDoc}
*/
public String getId(RequestContext request)
{
String typeId = request.getTarget().getParameter("typeid");
if (typeId == null)
{
return "cmis:types";
}
return typeId;
}
/**
* {@inheritDoc}
*/
public String getName(TypeDefinition entry) throws ResponseContextException
{
return entry.getDisplayName();
}
/**
* {@inheritDoc}
*/
public String getTitle(TypeDefinition entry) throws ResponseContextException
{
return entry.getDisplayName();
}
/**
* {@inheritDoc}
*/
public String getTitle(RequestContext request)
{
return "Cmis Types";
}
/**
* {@inheritDoc}
*/
public Date getUpdated(TypeDefinition entry) throws ResponseContextException
{
// TODO must be determined ones. Types are not created in runtime.
return new Date();
}
/**
* {@inheritDoc}
*/
@Override
public ResponseContext postEntry(RequestContext request)
{
Entry entry;
try
{
entry = getEntryFromRequest(request);
}
catch (ResponseContextException rce)
{
return rce.getResponseContext();
}
try
{
Connection connection = getConnection(request);
TypeDefinitionTypeElement typeElement = entry.getFirstChild(AtomCMIS.TYPE);
TypeDefinition type = typeElement.getTypeDefinition();
String typeId = connection.addType(type);
boolean includePropertyDefinition =
getBooleanParameter(request, AtomCMIS.PARAM_INCLUDE_PROPERTY_DEFINITIONS, false);
// Updated (formed) type definition.
type = connection.getTypeDefinition(typeId, includePropertyDefinition);
entry = request.getAbdera().getFactory().newEntry();
addEntryDetails(request, entry, request.getResolvedUri(), type);
}
catch (InvalidArgumentException iae)
{
return createErrorResponse(iae, 400);
}
catch (ConstraintException ce)
{
return createErrorResponse(ce, 409);
}
catch (TypeNotFoundException tnfe)
{
return createErrorResponse(tnfe, 404);
}
catch (StorageException re)
{
return createErrorResponse(re, 500);
}
catch (ResponseContextException rce)
{
return rce.getResponseContext();
}
Map<String, String> params = new HashMap<String, String>();
String link = request.absoluteUrlFor(TargetType.ENTRY, params);
return buildCreateEntryResponse(link, entry);
}
/**
* {@inheritDoc}
*/
@Override
protected String addEntryDetails(RequestContext request, Entry entry, IRI feedIri, TypeDefinition type)
throws ResponseContextException
{
entry.setId(type.getId());
entry.setTitle(type.getDisplayName());
entry.setUpdated(AtomUtils.getAtomDate(Calendar.getInstance()));
entry.setPublished(AtomUtils.getAtomDate(Calendar.getInstance()));
entry.setSummary("");
Person p = request.getAbdera().getFactory().newAuthor();
p.setName(getAuthor(request));
entry.addAuthor(p);
//Service link.
entry.addLink(getServiceLink(request), AtomCMIS.LINK_SERVICE, AtomCMIS.MEDIATYPE_ATOM_SERVICE, null, null, -1);
// Self link.
String self = getObjectTypeLink(getId(type), request);
entry.addLink(self, AtomCMIS.LINK_SELF, AtomCMIS.MEDIATYPE_ATOM_ENTRY, null, null, -1);
// Parent type link.
String parentTypeId = type.getParentId();
if (parentTypeId != null)
{
// Does not provided for root types.
String parent = getObjectTypeLink(parentTypeId, request);
entry.addLink(parent, AtomCMIS.LINK_UP, AtomCMIS.MEDIATYPE_ATOM_ENTRY, null, null, -1);
}
// Down link is link to children types.
String childrenLink = getTypeChildrenLink(type.getId(), request);
entry.addLink(childrenLink, AtomCMIS.LINK_DOWN, AtomCMIS.MEDIATYPE_ATOM_FEED, null, null, -1);
// Down link is link to descendant types.
String descendatsLink = getTypeDescendantsLink(type.getId(), request);
entry.addLink(descendatsLink, AtomCMIS.LINK_DOWN, AtomCMIS.MEDIATYPE_CMISTREE, null, null, -1);
TypeDefinitionTypeElement objectElement =
new TypeDefinitionTypeElement(request.getAbdera().getFactory(), AtomCMIS.TYPE);
objectElement.build(type);
entry.addExtension(objectElement);
return self;
}
/**
* Get link to AtomPub Document that describes direct descendants type for
* specified type <code>id</code>.
*
* @param typeId type id
* @param request request context
* @return link to AtomPub Document that describes direct descendants type
* for specified type <code>id</code>
*/
protected String getTypeChildrenLink(String typeId, RequestContext request)
{
Map<String, String> params = new HashMap<String, String>();
params.put("repoid", getRepositoryId(request));
params.put("atomdoctype", "types");
params.put("id", typeId);
String type = request.absoluteUrlFor(TargetType.ENTRY, params);
return type;
}
/**
* Get link to AtomPub Document that describes all descendants type for
* specified type <code>id</code>.
*
* @param typeId type id
* @param request request context
* @return link to AtomPub Document that describes all descendants type for
* specified type <code>id</code>
*/
protected String getTypeDescendantsLink(String typeId, RequestContext request)
{
Map<String, String> params = new HashMap<String, String>();
params.put("repoid", getRepositoryId(request));
params.put("atomdoctype", "typedescendants");
params.put("id", typeId);
String type = request.absoluteUrlFor(TargetType.ENTRY, params);
return type;
}
/**
* Delete entry.
*
* @param typeId the type id
* @param request the request
* @throws ResponseContextException the response context exception
*/
@Override
public void deleteEntry(String typeId, RequestContext request) throws ResponseContextException
{
try
{
Connection connection = getConnection(request);
connection.getStorage().removeType(typeId);
}
catch (ConstraintException cve)
{
throw new ResponseContextException(createErrorResponse(cve, 409));
}
catch (TypeNotFoundException tnfe)
{
throw new ResponseContextException(createErrorResponse(tnfe, 404));
}
catch (InvalidArgumentException iae)
{
throw new ResponseContextException(createErrorResponse(iae, 400));
}
catch (StorageException re)
{
throw new ResponseContextException(createErrorResponse(re, 500));
}
}
}