--- /dev/null
+/**
+ * TenantClient.java
+ *
+ * {Purpose of This Class}
+ *
+ * {Other Notes Relating to This Class (Optional)}
+ *
+ * $LastChangedBy: $
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ *
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright (C) 2009 {Contributing Institution}
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.client;
+
+import javax.ws.rs.core.Response;
+import org.jboss.resteasy.client.ClientResponse;
+
+import org.collectionspace.services.account.Tenant;
+import org.collectionspace.services.account.TenantsList;
+
+/**
+ * A TenantClient.
+
+ * @version $Revision:$
+ */
+public class TenantClient extends AbstractServiceClientImpl<TenantsList, Tenant,
+ Tenant, TenantProxy> {
+ public static final String SERVICE_NAME = "tenants";
+ public static final String SERVICE_PATH_COMPONENT = SERVICE_NAME;
+ public static final String SERVICE_PATH = "/" + SERVICE_PATH_COMPONENT;
+
+ @Override
+ public String getServiceName() {
+ return SERVICE_NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.collectionspace.services.client.AbstractServiceClientImpl#getServicePathComponent()
+ */
+ @Override
+ public String getServicePathComponent() {
+ return SERVICE_NAME;
+ }
+
+ @Override
+ public Class<TenantProxy> getProxyClass() {
+ return TenantProxy.class;
+ }
+
+ /*
+ * CRUD+L Methods
+ */
+
+ /**
+ * @return response
+ * @see org.collectionspace.hello.client.TenantProxy#readList()
+ */
+ public ClientResponse<TenantsList> readList() {
+ return getProxy().readList();
+ }
+
+ public ClientResponse<TenantsList> readSearchList(String name, String disabled) {
+ return getProxy().readSearchList(name, disabled);
+ }
+
+ /**
+ * @param csid
+ * @return response
+ * @see org.collectionspace.hello.client.TenantProxy#getTenant(java.lang.String)
+ */
+ public ClientResponse<Tenant> read(String id) {
+ return getProxy().read(id);
+ }
+
+ /**
+ * @param multipart
+ * @param tenant
+ * @return response
+ * @see org.collectionspace.hello.client.TenantProxy#create(org.collectionspace.services.account.Tenant)
+ */
+ public ClientResponse<Response> create(Tenant multipart) {
+ return getProxy().create(multipart);
+ }
+
+ /**
+ * @param csid
+ * @param multipart
+ * @param tenant
+ * @return response
+ * @see org.collectionspace.hello.client.TenantProxy#updateTenant(java.lang.Long, org.collectionspace.services.account.Tenant)
+ */
+ public ClientResponse<Tenant> update(String id, Tenant multipart) {
+ return getProxy().update(id, multipart);
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ */
+
+package org.collectionspace.services.client;
+
+import org.collectionspace.services.account.Tenant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author
+ */
+public class TenantFactory {
+ static private final Logger logger = LoggerFactory.getLogger(TenantFactory.class);
+
+ /**
+ * create tenant instance
+ * @param screenName
+ * @param userName
+ * @param passwd
+ * @param email
+ * @param tenantId add non-null tenant id else let service take tenant id of
+ * the authenticated user
+ * @param useScreenName
+ * @param invalidTenant
+ * @param useUser
+ * @param usePassword
+ * @return
+ */
+ public static Tenant createTenantInstance(String id,
+ String name, boolean disabled) {
+
+ Tenant tenant = new Tenant();
+ tenant.setName(name);
+ tenant.setId(id);
+ tenant.setDisabled(disabled);
+ return tenant;
+
+}
+
+}
--- /dev/null
+/**
+ * TenantProxy.java
+ *
+ * {Purpose of This Class}
+ *
+ * {Other Notes Relating to This Class (Optional)}
+ *
+ * $LastChangedBy: $
+ * $LastChangedRevision: $
+ * $LastChangedDate: $
+ *
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+ *
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+ *
+ * Copyright (C) 2009 {Contributing Institution}
+ *
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+ *
+ * You may obtain a copy of the ECL 2.0 License at
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+ */
+package org.collectionspace.services.client;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.services.account.Tenant;
+import org.collectionspace.services.account.TenantsList;
+import org.jboss.resteasy.client.ClientResponse;
+
+/**
+ * @version $Revision:$
+ */
+@Path("/tenants/")
+@Produces({"application/xml"})
+@Consumes({"application/xml"})
+public interface TenantProxy extends CollectionSpaceProxy<TenantsList> {
+
+ @GET
+ @Produces({"application/xml"})
+ ClientResponse<TenantsList> readList();
+
+ @GET
+ @Produces({"application/xml"})
+ ClientResponse<TenantsList> readSearchList(
+ @QueryParam("name") String name,
+ @QueryParam("disabled") String disabled);
+
+ //(C)reate
+ @POST
+ ClientResponse<Response> create(Tenant multipart);
+
+ //(R)ead
+ @GET
+ @Path("/{csid}")
+ ClientResponse<Tenant> read(@PathParam("id") String id);
+
+ //(U)pdate
+ @PUT
+ @Path("/{csid}")
+ ClientResponse<Tenant> update(@PathParam("id") String id, Tenant multipart);
+}
</xs:element>
</xs:sequence>
</xs:complexType>
+
+ <xs:element name="tenants-list">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation>
+ TenantsList contains information about one or more
+ tenants. An instance of this type could be returned on
+ index and search operations.
+ </xs:documentation>
+ <xs:appinfo>
+ <hj:ignored/>
+ </xs:appinfo>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="abstractCommonList">
+ <xs:sequence>
+ <xs:element name="tenant-list-item" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:appinfo>
+ <hj:ignored/>
+ </xs:appinfo>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="id" type="xs:string" minOccurs="1"/>
+ <xs:element name="name" type="xs:string" minOccurs="1" />
+ <xs:element name="disabled" type="xs:boolean" minOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+
+
</xs:schema>
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2012 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ *
+ */
+
+package org.collectionspace.services.account;
+
+import org.collectionspace.services.account.storage.TenantStorageClient;
+import org.collectionspace.services.client.TenantClient;
+import org.collectionspace.services.client.PayloadOutputPart;
+import org.collectionspace.services.common.SecurityResourceBase;
+import org.collectionspace.services.common.ServiceMessages;
+import org.collectionspace.services.common.context.RemoteServiceContextFactory;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.context.ServiceContextFactory;
+import org.collectionspace.services.common.storage.StorageClient;
+import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
+import org.jboss.resteasy.util.HttpResponseCodes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+
+/** TenantResource provides RESTful interface to the tenant service
+ *
+ * The TenantResource is tied to the account package for historical
+ * reasons, and because it is toes so closely to the notion of accounts
+ * and IAM.
+ */
+@Path(TenantClient.SERVICE_PATH)
+@Consumes("application/xml")
+@Produces("application/xml")
+public class TenantResource extends SecurityResourceBase {
+
+ final Logger logger = LoggerFactory.getLogger(TenantResource.class);
+ final StorageClient storageClient = new TenantStorageClient();
+
+ @Override
+ protected String getVersionString() {
+ return "$LastChangedRevision: 1165 $";
+ }
+
+ @Override
+ public String getServiceName() {
+ return TenantClient.SERVICE_NAME;
+ }
+
+ @Override
+ public Class<Tenant> getCommonPartClass() {
+ return Tenant.class;
+ }
+
+ @Override
+ public ServiceContextFactory<Tenant, Tenant> getServiceContextFactory() {
+ return (ServiceContextFactory<Tenant, Tenant>) RemoteServiceContextFactory.get();
+ }
+
+ @Override
+ public StorageClient getStorageClient(ServiceContext ctx) {
+ //FIXME use ctx to identify storage client
+ return storageClient;
+ }
+
+ @POST
+ public Response createTenant(Tenant input) {
+ return create(input);
+ }
+
+ @GET
+ @Path("{csid}")
+ public Tenant getTenant(@PathParam("csid") String csid) {
+ return (Tenant)get(csid, Tenant.class);
+ }
+
+ @GET
+ @Produces("application/xml")
+ public TenantsList getTenantList(@Context UriInfo ui) {
+ TenantsList result = (TenantsList)getList(ui, Tenant.class);
+ if(logger.isTraceEnabled()) {
+ PayloadOutputPart ppo = new PayloadOutputPart(TenantsList.class.getSimpleName(),
+ result);
+ System.out.println(ppo.asXML());
+ }
+ return result;
+ }
+
+ @PUT
+ @Path("{csid}")
+ public Tenant updateTenant(@PathParam("csid") String csid,Tenant theUpdate) {
+ return (Tenant)update(csid, theUpdate, Tenant.class);
+ }
+
+
+ @DELETE
+ @Path("{csid}")
+ public Response deleteTenant(@Context UriInfo uriInfo, @PathParam("csid") String csid) {
+ logger.debug("deleteTenant with csid=" + csid);
+ ensureCSID(csid, ServiceMessages.DELETE_FAILED);
+ try {
+ ServiceContext<Tenant, Tenant> ctx = createServiceContext((Tenant) null,
+ Tenant.class, uriInfo);
+ getStorageClient(ctx).delete(ctx, csid);
+ return Response.status(HttpResponseCodes.SC_OK).build();
+ } catch (Exception e) {
+ throw bigReThrow(e, ServiceMessages.DELETE_FAILED, csid);
+ }
+
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ */
+package org.collectionspace.services.account.storage;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.lang.StringUtils;
+import org.collectionspace.services.account.Tenant;
+import org.collectionspace.services.account.TenantsList;
+import org.collectionspace.services.account.TenantListItem;
+
+import org.collectionspace.services.client.TenantClient;
+import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.DocumentFilter;
+import org.collectionspace.services.common.document.DocumentWrapper;
+import org.collectionspace.services.common.document.JaxbUtils;
+import org.collectionspace.services.common.security.SecurityUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author
+ */
+public class TenantDocumentHandler
+ extends JpaDocumentHandler<Tenant, TenantsList, Tenant, List> {
+
+ private final Logger logger = LoggerFactory.getLogger(AccountDocumentHandler.class);
+ private Tenant tenant;
+ private TenantsList tenantList;
+
+ @Override
+ public void handleCreate(DocumentWrapper<Tenant> wrapDoc) throws Exception {
+ }
+
+ @Override
+ public void handleUpdate(DocumentWrapper<Tenant> wrapDoc) throws Exception {
+ }
+
+ @Override
+ public void completeUpdate(DocumentWrapper<Tenant> wrapDoc) throws Exception {
+ Tenant upAcc = wrapDoc.getWrappedObject();
+ getServiceContext().setOutput(upAcc);
+ }
+
+ @Override
+ public void handleGet(DocumentWrapper<Tenant> wrapDoc) throws Exception {
+ setCommonPart(extractCommonPart(wrapDoc));
+ getServiceContext().setOutput(tenant);
+ }
+
+ @Override
+ public void handleGetAll(DocumentWrapper<List> wrapDoc) throws Exception {
+ TenantsList tenList = extractCommonPartList(wrapDoc);
+ setCommonPartList(tenList);
+ getServiceContext().setOutput(getCommonPartList());
+ }
+
+ @Override
+ public Tenant extractCommonPart(
+ DocumentWrapper<Tenant> wrapDoc)
+ throws Exception {
+ return wrapDoc.getWrappedObject();
+ }
+
+ @Override
+ public void fillCommonPart(Tenant obj, DocumentWrapper<Tenant> wrapDoc)
+ throws Exception {
+ throw new UnsupportedOperationException("operation not relevant for TenantDocumentHandler");
+ }
+
+ @Override
+ public TenantsList extractCommonPartList(
+ DocumentWrapper<List> wrapDoc)
+ throws Exception {
+
+ TenantsList tenList = this.extractPagingInfo(new TenantsList(), wrapDoc);
+// TenantsList accList = new TenantsList();
+ List<TenantListItem> list = tenList.getTenantListItem();
+
+ for (Object obj : wrapDoc.getWrappedObject()) {
+ Tenant tenant = (Tenant) obj;
+ TenantListItem tenListItem = new TenantListItem();
+ tenListItem.setId(tenant.getId());
+ tenListItem.setName(tenant.getName());
+ tenListItem.setDisabled(tenant.isDisabled());
+ list.add(tenListItem);
+ }
+ return tenList;
+ }
+
+ @Override
+ public Tenant getCommonPart() {
+ return tenant;
+ }
+
+ @Override
+ public void setCommonPart(Tenant tenant) {
+ this.tenant = tenant;
+ }
+
+ @Override
+ public TenantsList getCommonPartList() {
+ return tenantList;
+ }
+
+ @Override
+ public void setCommonPartList(TenantsList tenantList) {
+ this.tenantList = tenantList;
+ }
+
+ @Override
+ public String getQProperty(
+ String prop) {
+ return null;
+ }
+
+ @Override
+ public DocumentFilter createDocumentFilter() {
+ DocumentFilter filter = new TenantJpaFilter(this.getServiceContext());
+ return filter;
+ }
+
+ /* (non-Javadoc)
+ * @see org.collectionspace.services.common.document.DocumentHandler#initializeDocumentFilter(org.collectionspace.services.common.context.ServiceContext)
+ */
+ public void initializeDocumentFilter(ServiceContext ctx) {
+ // set a default document filter in this method
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+
+ */
+package org.collectionspace.services.account.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.security.SecurityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author
+ */
+public class TenantJpaFilter extends JpaDocumentFilter {
+
+ private final Logger logger = LoggerFactory.getLogger(TenantJpaFilter.class);
+
+ public TenantJpaFilter(ServiceContext ctx) {
+ super(ctx);
+ }
+
+ @Override
+ public List<ParamBinding> buildWhereForSearch(StringBuilder queryStrBldr) {
+
+ List<ParamBinding> paramList = new ArrayList<ParamBinding>();
+ String name = null;
+ List<String> nvals = getQueryParam(TenantStorageConstants.Q_NAME);
+ if (null != nvals && nvals.size() > 0) {
+ name = nvals.get(0);
+ }
+ boolean csAdmin = SecurityUtils.isCSpaceAdmin();
+ if (null != name && !name.isEmpty()) {
+ queryStrBldr.append(" WHERE UPPER(a.");
+ queryStrBldr.append(TenantStorageConstants.NAME_FIELD);
+ queryStrBldr.append(") LIKE :");
+ queryStrBldr.append(" :" + TenantStorageConstants.Q_NAME);
+ paramList.add(new ParamBinding(
+ TenantStorageConstants.Q_NAME, "%" + name.toUpperCase() + "%"));
+ }
+
+ String includeDisabledStr = null;
+ List<String> inclDisVals = getQueryParam(TenantStorageConstants.Q_INCLUDE_DISABLED);
+ if (null != inclDisVals && inclDisVals.size() > 0) {
+ includeDisabledStr = inclDisVals.get(0);
+ }
+ // Default is to exclude disabled tenants, unless they specify to include them
+ boolean includeDisabled = (null != includeDisabledStr && !includeDisabledStr.isEmpty()
+ && Boolean.parseBoolean(includeDisabledStr));
+ // If excluding, then add a clause
+ if(!includeDisabled) {
+ queryStrBldr.append(" WHERE NOT a.");
+ queryStrBldr.append(TenantStorageConstants.DISABLED_FIELD);
+ }
+
+ if (logger.isDebugEnabled()) {
+ String query = queryStrBldr.toString();
+ logger.debug("query=" + query);
+ }
+
+ return paramList;
+ }
+
+ @Override
+ public List<ParamBinding> buildWhere(StringBuilder queryStrBldr) {
+ return new ArrayList<ParamBinding>();
+ }
+
+ @Override
+ protected String addTenant(boolean append, List<ParamBinding> paramList) {
+ // unused for tenants - special case
+ return "";
+ }
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ */
+package org.collectionspace.services.account.storage;
+
+import java.util.Date;
+import java.util.HashMap;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import org.collectionspace.services.account.Tenant;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentFilter;
+import org.collectionspace.services.common.document.DocumentHandler;
+import org.collectionspace.services.common.document.DocumentHandler.Action;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
+import org.collectionspace.services.common.document.DocumentWrapper;
+import org.collectionspace.services.common.document.DocumentWrapperImpl;
+import org.collectionspace.services.common.document.JaxbUtils;
+import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl;
+import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TenantStorageClient deals with both Account and CSIdP's
+ * state in persistent storage. The rationale behind creating this class is that
+ * this class manages persistence for both account and CSIP's user. Transactions
+ * are used where possible to perform the persistence operations atomically.
+ * @author
+ */
+public class TenantStorageClient extends JpaStorageClientImpl {
+
+ private final Logger logger = LoggerFactory.getLogger(TenantStorageClient.class);
+
+ public TenantStorageClient() {
+ }
+
+ @Override
+ public String create(ServiceContext ctx,
+ DocumentHandler handler) throws BadRequestException,
+ DocumentException {
+
+ if (ctx == null) {
+ throw new IllegalArgumentException(
+ "TenantStorageClient.create : ctx is missing");
+ }
+ if (handler == null) {
+ throw new IllegalArgumentException(
+ "TenantStorageClient.create: handler is missing");
+ }
+ EntityManagerFactory emf = null;
+ EntityManager em = null;
+ Tenant tenant = (Tenant) handler.getCommonPart();
+ try {
+ handler.prepare(Action.CREATE);
+ DocumentWrapper<Tenant> wrapDoc =
+ new DocumentWrapperImpl<Tenant>(tenant);
+ handler.handle(Action.CREATE, wrapDoc);
+ emf = JpaStorageUtils.getEntityManagerFactory();
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ tenant.setCreatedAtItem(new Date());
+ em.persist(tenant);
+ em.getTransaction().commit();
+ handler.complete(Action.CREATE, wrapDoc);
+ return (String) JaxbUtils.getValue(tenant, "getId");
+ } catch (BadRequestException bre) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ throw bre;
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception ", e);
+ }
+ boolean uniqueConstraint = false;
+ try {
+ if(em.find(Tenant.class, tenant.getId()) != null) {
+ //might be unique constraint violation
+ uniqueConstraint = true;
+ }
+ } catch(Exception ignored) {
+ //Ignore - we just care if exists
+ }
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ if (uniqueConstraint) {
+ String msg = "TenantId exists. Non unique tenantId=" + tenant.getId();
+ logger.error(msg);
+ throw new BadRequestException(msg);
+ }
+ throw new DocumentException(e);
+ } finally {
+ if (em != null) {
+ JpaStorageUtils.releaseEntityManagerFactory(emf);
+ }
+ }
+ }
+
+ @Override
+ public void get(ServiceContext ctx, String id, DocumentHandler handler)
+ throws DocumentNotFoundException, DocumentException {
+ if (ctx == null) {
+ throw new IllegalArgumentException(
+ "get: ctx is missing");
+ }
+ if (handler == null) {
+ throw new IllegalArgumentException(
+ "get: handler is missing");
+ }
+ DocumentFilter docFilter = handler.getDocumentFilter();
+ if (docFilter == null) {
+ docFilter = handler.createDocumentFilter();
+ }
+ EntityManagerFactory emf = null;
+ EntityManager em = null;
+ try {
+ handler.prepare(Action.GET);
+ Object o = null;
+ String whereClause = " where id = :id";
+ HashMap<String, Object> params = new HashMap<String, Object>();
+ params.put("id", id);
+
+ o = JpaStorageUtils.getEntity(
+ "org.collectionspace.services.account.Tenant", whereClause, params);
+ if (null == o) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ String msg = "could not find entity with id=" + id;
+ throw new DocumentNotFoundException(msg);
+ }
+ DocumentWrapper<Object> wrapDoc = new DocumentWrapperImpl<Object>(o);
+ handler.handle(Action.GET, wrapDoc);
+ handler.complete(Action.GET, wrapDoc);
+ } catch (DocumentException de) {
+ throw de;
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ } finally {
+ if (emf != null) {
+ JpaStorageUtils.releaseEntityManagerFactory(emf);
+ }
+ }
+ }
+
+ @Override
+ public void update(ServiceContext ctx, String id, DocumentHandler handler)
+ throws BadRequestException, DocumentNotFoundException,
+ DocumentException {
+ if (ctx == null) {
+ throw new IllegalArgumentException(
+ "TenantStorageClient.update : ctx is missing");
+ }
+ if (handler == null) {
+ throw new IllegalArgumentException(
+ "TenantStorageClient.update: handler is missing");
+ }
+ EntityManagerFactory emf = null;
+ EntityManager em = null;
+ try {
+ handler.prepare(Action.UPDATE);
+ Tenant tenantReceived = (Tenant) handler.getCommonPart();
+ emf = JpaStorageUtils.getEntityManagerFactory();
+ em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Tenant tenantFound = getTenant(em, id);
+ checkAllowedUpdates(tenantReceived, tenantFound);
+ DocumentWrapper<Tenant> wrapDoc =
+ new DocumentWrapperImpl<Tenant>(tenantFound);
+ handler.handle(Action.UPDATE, wrapDoc);
+ em.getTransaction().commit();
+ handler.complete(Action.UPDATE, wrapDoc);
+ } catch (BadRequestException bre) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ throw bre;
+ } catch (DocumentException de) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ throw de;
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ } finally {
+ if (emf != null) {
+ JpaStorageUtils.releaseEntityManagerFactory(emf);
+ }
+ }
+ }
+
+ @Override
+ public void delete(ServiceContext ctx, String id)
+ throws DocumentNotFoundException,
+ DocumentException {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("deleting entity with id=" + id);
+ }
+ if (ctx == null) {
+ throw new IllegalArgumentException(
+ "TenantStorageClient.delete : ctx is missing");
+ }
+ EntityManagerFactory emf = null;
+ EntityManager em = null;
+ try {
+ emf = JpaStorageUtils.getEntityManagerFactory();
+ em = emf.createEntityManager();
+
+ Tenant tenantFound = getTenant(em, id);
+ em.getTransaction().begin();
+ em.remove(tenantFound);
+ em.getTransaction().commit();
+
+ } catch (DocumentException de) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ throw de;
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception ", e);
+ }
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ throw new DocumentException(e);
+ } finally {
+ if (emf != null) {
+ JpaStorageUtils.releaseEntityManagerFactory(emf);
+ }
+ }
+ }
+
+ private Tenant getTenant(EntityManager em, String id) throws DocumentNotFoundException {
+ Tenant tenantFound = em.find(Tenant.class, id);
+ if (tenantFound == null) {
+ if (em != null && em.getTransaction().isActive()) {
+ em.getTransaction().rollback();
+ }
+ String msg = "could not find account with id=" + id;
+ logger.error(msg);
+ throw new DocumentNotFoundException(msg);
+ }
+ return tenantFound;
+ }
+
+ private boolean checkAllowedUpdates(Tenant toTenant, Tenant fromTenant) throws BadRequestException {
+ if (!fromTenant.getId().equals(toTenant.getId())) {
+ String msg = "Cannot change Tenant Id!";
+ logger.error(msg);
+ throw new BadRequestException(msg);
+ }
+ return true;
+ }
+
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ *//**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.collectionspace.services.account.storage;
+
+/**
+ * TenantStorageConstants declares query params, etc.
+ * @author
+ */
+public class TenantStorageConstants {
+
+ final public static String Q_NAME = "name";
+ final public static String Q_INCLUDE_DISABLED= "inclDis";
+
+ final public static String NAME_FIELD = "name";
+ final public static String DISABLED_FIELD = "disabled";
+}
--- /dev/null
+/**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ *//**
+ * This document is a part of the source code and related artifacts
+ * for CollectionSpace, an open source collections management system
+ * for museums and related institutions:
+
+ * http://www.collectionspace.org
+ * http://wiki.collectionspace.org
+
+ * Copyright 2009 University of California at Berkeley
+
+ * Licensed under the Educational Community License (ECL), Version 2.0.
+ * You may not use this file except in compliance with this License.
+
+ * You may obtain a copy of the ECL 2.0 License at
+
+ * https://source.collectionspace.org/collection-space/LICENSE.txt
+
+ * 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.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.collectionspace.services.account.storage;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+import org.collectionspace.services.account.Tenant;
+import org.collectionspace.services.common.ServiceMessages;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.DocumentHandler.Action;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
+import org.collectionspace.services.common.document.InvalidDocumentException;
+import org.collectionspace.services.common.document.ValidatorHandler;
+import org.collectionspace.services.common.storage.jpa.JpaStorageUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author
+ */
+public class TenantValidatorHandler implements ValidatorHandler {
+
+ final Logger logger = LoggerFactory.getLogger(AccountValidatorHandler.class);
+
+ @Override
+ public void validate(Action action, ServiceContext ctx)
+ throws InvalidDocumentException {
+ if (logger.isDebugEnabled()) {
+ logger.debug("validate() action=" + action.name());
+ }
+ try {
+ Tenant tenant = (Tenant) ctx.getInput();
+ StringBuilder msgBldr = new StringBuilder(ServiceMessages.VALIDATION_FAILURE);
+ boolean invalid = false;
+
+ if (action.equals(Action.CREATE)) {
+
+ //create specific validation here
+ if (StringUtils.isEmpty(tenant.getId())) {
+ invalid = true;
+ msgBldr.append("\nId : missing");
+ }
+ if (StringUtils.isEmpty(tenant.getName())) {
+ invalid = true;
+ msgBldr.append("\nName : missing");
+ }
+ } else if (action.equals(Action.UPDATE)) {
+ //update specific validation here
+ if (StringUtils.isEmpty(tenant.getName())) {
+ invalid = true;
+ msgBldr.append("\nName : missing");
+ }
+ }
+ if (invalid) {
+ String msg = msgBldr.toString();
+ logger.error(msg);
+ throw new InvalidDocumentException(msg);
+ }
+ } catch (InvalidDocumentException ide) {
+ throw ide;
+ } catch (Exception e) {
+ throw new InvalidDocumentException(e);
+ }
+ }
+
+
+}