2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
24 package org.collectionspace.services.common.context;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
30 import java.util.Properties;
32 import javax.ws.rs.core.MultivaluedMap;
33 import javax.ws.rs.core.Request;
34 import javax.ws.rs.core.UriInfo;
36 import org.collectionspace.authentication.spi.AuthNContext;
37 import org.collectionspace.services.client.AuthorityClient;
38 import org.collectionspace.services.client.CollectionSpaceClient;
39 import org.collectionspace.services.client.IClientQueryParams;
40 import org.collectionspace.services.client.IQueryManager;
41 import org.collectionspace.services.client.workflow.WorkflowClient;
42 import org.collectionspace.services.common.ServiceMain;
43 import org.collectionspace.services.common.api.Tools;
44 import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;
45 import org.collectionspace.services.common.config.PropertyItemUtils;
46 import org.collectionspace.services.common.config.ServiceConfigUtils;
47 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
48 import org.collectionspace.services.common.document.DocumentHandler;
49 import org.collectionspace.services.common.document.DocumentFilter;
50 import org.collectionspace.services.common.document.ValidatorHandler;
51 import org.collectionspace.services.common.security.SecurityContext;
52 import org.collectionspace.services.common.security.SecurityContextImpl;
53 import org.collectionspace.services.common.security.UnauthorizedException;
54 import org.collectionspace.services.config.ClientType;
55 import org.collectionspace.services.config.service.ObjectPartType;
56 import org.collectionspace.services.config.service.ServiceBindingType;
57 import org.collectionspace.services.config.tenant.RemoteClientConfig;
58 import org.collectionspace.services.config.tenant.RepositoryDomainType;
59 import org.collectionspace.services.config.tenant.TenantBindingType;
60 import org.collectionspace.services.config.types.PropertyItemType;
61 import org.collectionspace.services.config.types.PropertyType;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
66 * AbstractServiceContext
68 * $LastChangedRevision: $
83 @SuppressWarnings("rawtypes")
84 public abstract class AbstractServiceContextImpl<IT, OT>
85 implements ServiceContext<IT, OT> {
88 final Logger logger = LoggerFactory.getLogger(AbstractServiceContextImpl.class);
90 /** The properties. */
91 Map<String, Object> properties = new HashMap<String, Object>();
92 /** The object part map. */
93 Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
94 /** The service binding. */
95 protected ServiceBindingType serviceBinding;
96 /** The tenant binding. */
97 private TenantBindingType tenantBinding;
98 /** repository domain used by the service */
99 private RepositoryDomainType repositoryDomain;
100 /** The override document type. */
101 private String overrideDocumentType = null;
102 /** The val handlers. */
103 private List<ValidatorHandler<IT, OT>> valHandlers = null;
104 /** The authority client -use for shared authority server */
105 private AuthorityClient authorityClient = null;
106 /** The doc handler. */
107 private DocumentHandler docHandler = null;
108 /** security context */
109 private SecurityContext securityContext;
110 /** The sessions JAX-RS URI information */
111 private UriInfo uriInfo;
112 /** The JAX-RS request information */
113 private Request requestInfo;
114 /** The current repository session */
115 private Object currentRepositorySession;
116 /** A reference count for the current repository session */
117 private int currentRepoSesssionRefCount = 0;
120 * Instantiates a new abstract service context impl.
122 private AbstractServiceContextImpl() {
123 // private constructor for singleton pattern
125 // request query params
126 /** The query params. */
127 private MultivaluedMap<String, String> queryParams;
130 * Instantiates a new abstract service context impl.
132 * @param serviceName the service name
134 * @throws UnauthorizedException the unauthorized exception
136 protected AbstractServiceContextImpl(String serviceName, UriInfo uriInfo) throws UnauthorizedException {
138 //establish security context
139 securityContext = new SecurityContextImpl(uriInfo);
140 //make sure tenant context exists
141 checkTenantContext();
143 String tenantId = securityContext.getCurrentTenantId();
144 if (AuthorizationCommon.ALL_TENANTS_MANAGER_TENANT_ID.equals(tenantId) ||
145 AuthNContext.ANONYMOUS_TENANT_ID.equals(tenantId)) {
146 // Tenant Manager has no tenant binding, so don't bother...
147 tenantBinding = null;
148 serviceBinding = null;
149 repositoryDomain = null;
151 //retrieve service bindings
152 TenantBindingConfigReaderImpl tReader =
153 ServiceMain.getInstance().getTenantBindingConfigReader();
154 tenantBinding = tReader.getTenantBinding(tenantId);
155 if (tenantBinding == null) {
156 String msg = "No tenant binding found for tenantId=" + tenantId
157 + " while processing request for service= " + serviceName;
159 throw new IllegalStateException(msg);
161 serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
162 if (serviceBinding == null) {
163 String msg = "No service binding found while processing request for "
164 + serviceName + " for tenant id=" + getTenantId()
165 + " name=" + getTenantName();
167 throw new IllegalStateException(msg);
169 if (logger.isDebugEnabled()) {
170 logger.debug("tenantId=" + tenantId
171 + " service binding=" + serviceBinding.getName());
173 repositoryDomain = tReader.getRepositoryDomain(tenantId, serviceName);
174 if (repositoryDomain != null) {
175 if (logger.isDebugEnabled()) {
176 logger.debug("tenantId=" + tenantId
177 + " repository doamin=" + repositoryDomain.getName());
183 public int getTimeoutParam(UriInfo ui) {
184 int result = DEFAULT_TX_TIMEOUT;
186 MultivaluedMap<String, String> queryParams = (ui == null) ? null : ui.getQueryParameters();
187 if (queryParams != null) {
188 String timeoutString = queryParams.getFirst(IClientQueryParams.IMPORT_TIMEOUT_PARAM);
189 if (timeoutString == null) {
190 timeoutString = queryParams.getFirst(IClientQueryParams.IMPORT_TIMOUT_PARAM);
193 if (timeoutString != null) {
195 result = Integer.parseInt(timeoutString);
196 } catch (NumberFormatException e) {
197 logger.warn("Transaction timeout period parameter could not be parsed. The characters in the parameter string must all be decimal digits. The Import service will use the default timeout period instead.",
207 public int getTimeoutSecs() {
208 UriInfo uriInfo = this.getUriInfo();
209 return this.getTimeoutParam(uriInfo);
213 * Returns TRUE unless the "recordUpdates" query param is set with a value of either "false", "FALSE", or "0"
217 public boolean shouldUpdateCoreValues() {
218 boolean recordUpdates = true;
220 MultivaluedMap<String, String> queryParams = getQueryParams();
221 String paramValue = queryParams.getFirst(IClientQueryParams.UPDATE_CORE_VALUES);
222 if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.FALSE.toString())) { // Find our if the caller wants us to record updates
223 recordUpdates = false;
224 } else if (paramValue != null && paramValue.equals(Long.toString(0))) {
225 recordUpdates = false;
228 return recordUpdates;
232 * Default value is 'FALSE'
233 * If this returns true, it means that the refname values in referencing objects (records that reference authority or vocabulary terms) will be updated
234 * regardless of their current value. This is sometimes needed when refname values become stale for one of several reasons.
238 public boolean shouldForceUpdateRefnameReferences() {
239 boolean forceUpdates = false;
241 MultivaluedMap<String, String> queryParams = getQueryParams();
242 String paramValue = queryParams.getFirst(IClientQueryParams.FORCE_REFNAME_UPDATES);
243 if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.TRUE.toString())) { // Find our if the caller wants us to force refname updates
245 } else if (paramValue != null && paramValue.equals(Long.toString(1))) {
254 * @see org.collectionspace.services.common.context.ServiceContext#getCommonPartLabel()
257 public String getCommonPartLabel() {
258 return getCommonPartLabel(getServiceName());
262 * @see org.collectionspace.services.common.context.ServiceContext#getCommonPartLabel(java.lang.String)
264 public String getCommonPartLabel(String schemaName) {
265 return schemaName.toLowerCase() + PART_LABEL_SEPARATOR + PART_COMMON_LABEL;
269 * @see org.collectionspace.services.common.context.ServiceContext#getPartsMetadata()
272 public Map<String, ObjectPartType> getPartsMetadata() {
273 if (objectPartMap.size() != 0) {
274 return objectPartMap;
276 ServiceBindingUtils.getPartsMetadata(getServiceBinding(), objectPartMap);
277 return objectPartMap;
281 * Gets the properties for part.
283 * @param partLabel the part label
285 * @return the properties for part
287 public List<PropertyItemType> getPropertiesForPart(String partLabel) {
288 Map<String, ObjectPartType> partMap = getPartsMetadata();
289 ObjectPartType part = partMap.get(partLabel);
291 throw new RuntimeException("No such part found: " + partLabel);
293 List<PropertyType> propNodeList = part.getProperties();
294 return propNodeList.isEmpty() ? null : propNodeList.get(0).getItem();
298 * @param partLabel The name of the scehma part to search in
299 * @param propName The name of the property (or properties) to find
300 * @param qualified Whether the returned values should be qualified with the
301 * partLabel. This is when the property values are schema field references.
302 * @return List of property values for the matched property on the named schema part.
304 public List<String> getPropertyValuesForPart(String partLabel, String propName, boolean qualified) {
305 List<PropertyItemType> allProps = getPropertiesForPart(partLabel);
306 return PropertyItemUtils.getPropertyValuesByName(allProps, propName,
307 (qualified ? (partLabel + ":") : null));
311 * @param propName The name of the property (or properties) to find
312 * @param qualified Whether the returned values should be qualified with the
313 * partLabel. This is when the property values are schema field references.
314 * @return List of property values for the matched property on any schema part.
316 public List<String> getAllPartsPropertyValues(String propName, boolean qualified) {
317 return ServiceBindingUtils.getAllPartsPropertyValues(getServiceBinding(), propName, qualified);
321 * @see org.collectionspace.services.common.context.ServiceContext#getServiceBindingPropertyValue(java.lang.String)
323 public String getServiceBindingPropertyValue(String propName) {
324 return ServiceBindingUtils.getPropertyValue(getServiceBinding(), propName);
328 * Gets the common part properties.
330 * @return the common part properties
332 public List<PropertyItemType> getCommonPartProperties() {
333 return getPropertiesForPart(getCommonPartLabel());
337 * @param propName The name of the property (or properties) to find
338 * @param qualified Whether the returned values should be qualified with the
339 * partLabel. This is when the property values are schema field references.
340 * @return List of property values for the matched property on the common schema part.
342 public List<String> getCommonPartPropertyValues(String propName, boolean qualified) {
343 return getPropertyValuesForPart(getCommonPartLabel(), propName, qualified);
347 * @see org.collectionspace.services.common.context.ServiceContext#getQualifiedServiceName()
350 public String getQualifiedServiceName() {
351 return TenantBindingConfigReaderImpl.getTenantQualifiedServiceName(getTenantId(), getServiceName());
355 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryClientName()
358 public String getRepositoryClientName() {
359 if (repositoryDomain == null) {
362 return repositoryDomain.getRepositoryClient();
366 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryClientType()
369 public ClientType getRepositoryClientType() {
370 //assumption: there is only one repository client configured
371 return ServiceMain.getInstance().getClientType();
375 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryDomainName()
378 public String getRepositoryDomainName() {
379 if (repositoryDomain == null) {
382 return repositoryDomain.getName();
386 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryDomainName()
389 public String getRepositoryDomainStorageName() {
390 if (repositoryDomain == null) {
393 return repositoryDomain.getStorageName();
397 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryWorkspaceId()
400 public String getRepositoryWorkspaceId() {
401 return ServiceMain.getInstance().getWorkspaceId(getTenantId(), getServiceName());
405 * @see org.collectionspace.services.common.context.ServiceContext#getRepositoryWorkspaceName()
408 public String getRepositoryWorkspaceName() {
409 //service name is workspace name by convention
410 return serviceBinding.getName();
414 * @see org.collectionspace.services.common.context.ServiceContext#getServiceBinding()
417 public ServiceBindingType getServiceBinding() {
418 return serviceBinding;
422 * @see org.collectionspace.services.common.context.ServiceContext#getServiceName()
425 public String getServiceName() {
426 return serviceBinding.getName();
430 * @see org.collectionspace.services.common.context.ServiceContext#getDocumentType()
433 public String getDocumentType() {
434 // If they have not overridden the setting, use the type of the service
436 return (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
440 public String getTenantQualifiedDoctype(String docType) {
441 // If they have not overridden the setting, use the type of the service
443 String result = ServiceBindingUtils.getTenantQualifiedDocType(this.getTenantId(), docType);
449 public String getTenantQualifiedDoctype() {
450 String docType = (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
451 return getTenantQualifiedDoctype(docType);
455 * @see org.collectionspace.services.common.context.ServiceContext#setDocumentType(java.lang.String)
458 public void setDocumentType(String docType) {
459 overrideDocumentType = docType;
463 * @see org.collectionspace.services.common.context.ServiceContext#getSecurityContext()
466 public SecurityContext getSecurityContext() {
467 return securityContext;
471 * @see org.collectionspace.services.common.context.ServiceContext#getUserId()
474 public String getUserId() {
475 return securityContext.getUserId();
479 * @see org.collectionspace.services.common.context.ServiceContext#getTenantId()
482 public String getTenantId() {
483 return securityContext.getCurrentTenantId();
487 * @see org.collectionspace.services.common.context.ServiceContext#getTenantName()
490 public String getTenantName() {
491 return securityContext.getCurrentTenantName();
495 * @see org.collectionspace.services.common.context.ServiceContext#getInput()
498 public abstract IT getInput();
501 * @see org.collectionspace.services.common.context.ServiceContext#setInput(java.lang.Object)
504 public abstract void setInput(IT input);
507 * @see org.collectionspace.services.common.context.ServiceContext#getOutput()
510 public abstract OT getOutput();
513 * @see org.collectionspace.services.common.context.ServiceContext#setOutput(java.lang.Object)
516 public abstract void setOutput(OT output);
519 * @see org.collectionspace.services.common.context.ServiceContext#getProperties()
522 public Map<String, Object> getProperties() {
527 * @see org.collectionspace.services.common.context.ServiceContext#setProperties(java.util.Map)
530 public void setProperties(Map<String, Object> props) {
531 properties.putAll(props);
535 * @see org.collectionspace.services.common.context.ServiceContext#getProperty(java.lang.String)
537 public Object getProperty(String name) {
538 return properties.get(name);
542 * @see org.collectionspace.services.common.context.ServiceContext#setProperty(java.lang.String, java.lang.Object)
544 public void setProperty(String name, Object o) {
545 properties.put(name, o);
549 * checkTenantContext makss sure tenant context exists
553 * @throws UnauthorizedException the unauthorized exception
555 private void checkTenantContext() throws UnauthorizedException {
557 String tenantId = securityContext.getCurrentTenantId();
558 if (tenantId == null) {
559 String msg = "Could not find tenant context";
561 throw new UnauthorizedException(msg);
566 * Helps to filter for queries that either want to include or exclude documents in deleted workflow states.
571 private static String buildWorkflowWhereClause(MultivaluedMap<String, String> queryParams) {
572 String result = null;
574 String includeDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_NONDELETED);
575 String includeOnlyDeleted = queryParams.getFirst(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED);
577 if (includeDeleted != null && includeDeleted.equalsIgnoreCase(Boolean.FALSE.toString())) {
578 result = String.format("(ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s')",
579 WorkflowClient.WORKFLOWSTATE_DELETED, WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED, WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED);
580 } else if (includeOnlyDeleted != null && includeOnlyDeleted.equalsIgnoreCase(Boolean.TRUE.toString())) {
581 result = String.format("(ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s' AND ecm:currentLifeCycleState <> '%s')",
582 WorkflowClient.WORKFLOWSTATE_PROJECT, WorkflowClient.WORKFLOWSTATE_LOCKED, WorkflowClient.WORKFLOWSTATE_REPLICATED);
589 * Creates the document handler instance.
591 * @return the document handler
593 * @throws Exception the exception
595 private DocumentHandler createDocumentHandlerInstance() throws Exception {
596 docHandler = ServiceConfigUtils.createDocumentHandlerInstance(tenantBinding, serviceBinding);
598 // Create a default document filter
600 docHandler.setServiceContext(this);
601 DocumentFilter docFilter = docHandler.createDocumentFilter();
603 // If the context was created with query parameters,
604 // reflect the values of those parameters in the document filter
605 // to specify sort ordering, pagination, etc.
607 MultivaluedMap<String, String> queryParameters = this.getQueryParams();
608 if (queryParameters != null) {
609 docFilter.setSortOrder(queryParameters);
610 docFilter.setPagination(queryParameters);
611 String workflowWhereClause = buildWorkflowWhereClause(queryParameters);
612 if (workflowWhereClause != null) {
613 docFilter.appendWhereClause(workflowWhereClause, IQueryManager.SEARCH_QUALIFIER_AND);
617 docHandler.setDocumentFilter(docFilter);
623 * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHandler()
626 public DocumentHandler getDocumentHandler() throws Exception {
627 DocumentHandler result = docHandler;
628 // create a new instance if one does not yet exist
629 if (result == null) {
630 result = createDocumentHandlerInstance();
636 public void setDocumentHandler(DocumentHandler handler) throws Exception {
637 if (handler != null) {
638 docHandler = handler;
643 * @see org.collectionspace.services.common.context.ServiceContext#getDocumentHanlder(javax.ws.rs.core.MultivaluedMap)
646 public DocumentHandler getDocumentHandler(MultivaluedMap<String, String> queryParams) throws Exception {
647 DocumentHandler result = getDocumentHandler();
648 DocumentFilter documentFilter = result.getDocumentFilter(); //to see results in debugger variables view
649 documentFilter.setPagination(queryParams);
654 * If this element is set in the service binding then use it otherwise
655 * assume that asserts are NOT disabled.
657 private boolean disableValidationAsserts() {
659 Boolean disableAsserts = getServiceBinding().isDisableAsserts();
660 result = (disableAsserts != null) ? disableAsserts : false;
665 * @see org.collectionspace.services.common.context.ServiceContext#getValidatorHandlers()
668 public List<ValidatorHandler<IT, OT>> getValidatorHandlers() throws Exception {
669 if (valHandlers != null) {
672 List<String> handlerClazzes = getServiceBinding().getValidatorHandler();
673 List<ValidatorHandler<IT, OT>> handlers = new ArrayList<ValidatorHandler<IT, OT>>(handlerClazzes.size());
674 ClassLoader tccl = Thread.currentThread().getContextClassLoader();
675 for (String clazz : handlerClazzes) {
676 clazz = clazz.trim();
678 Class<?> c = tccl.loadClass(clazz);
679 if (disableValidationAsserts() == false) {
680 // enable validation assertions
681 tccl.setClassAssertionStatus(clazz, true);
683 if (ValidatorHandler.class.isAssignableFrom(c)) {
684 handlers.add((ValidatorHandler) c.newInstance());
686 } catch (ClassNotFoundException e) {
687 String msg = String.format("Missing document validation handler: '%s'.", clazz);
689 logger.trace(msg, e);
692 valHandlers = handlers;
697 * If one doesn't already exist, use the default properties filename to load a set of properties that
698 * will be used to create an HTTP client to a CollectionSpace instance.
701 public AuthorityClient getClient() throws Exception {
702 AuthorityClient result = authorityClient;
704 if (authorityClient == null) {
705 result = authorityClient = getClient(CollectionSpaceClient.DEFAULT_CLIENT_PROPERTIES_FILENAME);
712 * Use the properties filename passed in to load the URL and credentials that will be used
713 * to create a new HTTP client.
715 * Never uses or resets the this.authorityClient member. Always creates a new HTTP client using
716 * the loaded properties.
719 * @see org.collectionspace.services.common.context.ServiceContext#getClient(java.lang.String)
722 public AuthorityClient getClient(String clientPropertiesFilename) throws Exception {
723 AuthorityClient result = null;
725 Properties inProperties = Tools.loadProperties(clientPropertiesFilename, true);
726 result = getClient(inProperties);
731 public AuthorityClient getClient(Properties inProperties) throws Exception {
732 AuthorityClient result = null;
734 String authorityClientClazz = getServiceBinding().getClientHandler();
735 ClassLoader tccl = Thread.currentThread().getContextClassLoader();
736 authorityClientClazz = authorityClientClazz.trim();
738 Class<?> c = tccl.loadClass(authorityClientClazz);
739 if (AuthorityClient.class.isAssignableFrom(c)) {
740 result = authorityClient = ((AuthorityClient) c.newInstance());
741 result.setClientProperties(inProperties);
743 logger.error(String.format("The service binding clientHandler class '%s' for '%s' service was not of type AuthorityClient.",
744 authorityClientClazz, this.getServiceName()));
746 } catch (ClassNotFoundException e) {
747 String msg = String.format("Missing document validation handler: '%s'.", authorityClientClazz);
749 logger.trace(msg, e);
756 public AuthorityClient getClient(RemoteClientConfig remoteClientConfig) throws Exception {
757 AuthorityClient result = null;
759 Properties properties = new Properties();
760 properties.setProperty(AuthorityClient.URL_PROPERTY, remoteClientConfig.getUrl());
761 properties.setProperty(AuthorityClient.USER_PROPERTY, remoteClientConfig.getUser());
762 properties.setProperty(AuthorityClient.PASSWORD_PROPERTY, remoteClientConfig.getPassword());
763 properties.setProperty(AuthorityClient.SSL_PROPERTY, remoteClientConfig.getSsl());
764 properties.setProperty(AuthorityClient.AUTH_PROPERTY, remoteClientConfig.getAuth());
767 String tenantId = remoteClientConfig.getTenantId();
768 if (tenantId != null) {
769 properties.setProperty(AuthorityClient.TENANT_ID_PROPERTY, tenantId);
771 String tenantName = remoteClientConfig.getTenantName();
772 if (tenantName != null) {
773 properties.setProperty(AuthorityClient.TENANT_NAME_PROPERTY, tenantName);
776 result = getClient(properties);
782 public void addValidatorHandler(ValidatorHandler<IT, OT> validator) throws Exception {
783 if (valHandlers == null) {
784 valHandlers = new ArrayList<ValidatorHandler<IT, OT>>();
786 valHandlers.add(validator);
790 * @see java.lang.Object#toString()
793 public String toString() {
794 StringBuilder msg = new StringBuilder();
795 msg.append("AbstractServiceContext [");
796 msg.append("service name=" + serviceBinding.getName() + " ");
797 msg.append("service version=" + serviceBinding.getVersion() + " ");
798 msg.append("tenant id=" + tenantBinding.getId() + " ");
799 msg.append("tenant name=" + tenantBinding.getName() + " ");
800 msg.append(tenantBinding.getDisplayName() + " ");
801 if (repositoryDomain != null) {
802 msg.append("tenant repository domain=" + repositoryDomain.getName());
804 for (Map.Entry<String, Object> entry : properties.entrySet()) {
805 msg.append("property name=" + entry.getKey() + " value=" + entry.getValue().toString());
808 return msg.toString();
812 * @see org.collectionspace.services.common.context.ServiceContext#getQueryParams()
814 * When we first created these services, the RESTEasy query parameters used to be a modifiable map. That changed in a
815 * more recent version of RESTEasy, so we need to make a copy of the params into a modifiable map and return it instead.
818 public MultivaluedMap<String, String> getQueryParams() {
820 if (queryParams == null){
821 if (this.uriInfo != null){
822 queryParams = this.uriInfo.getQueryParameters();
825 if (queryParams == null){
826 queryParams = new org.jboss.resteasy.specimpl.MultivaluedMapImpl<String,String>();
828 return this.queryParams;
832 public MultivaluedMap<String, String> getQueryParamsPtr() {
833 return this.queryParams;
837 * @see org.collectionspace.services.common.context.ServiceContext#setQueryParams(javax.ws.rs.core.MultivaluedMap)
840 public void setQueryParams(MultivaluedMap<String, String> theQueryParams) {
841 this.queryParams = theQueryParams;
845 public void setUriInfo(UriInfo ui){
850 public UriInfo getUriInfo() {
855 public Request getRequestInfo() {
856 return this.requestInfo;
860 public void setRequestInfo(Request requestInfo) {
861 this.requestInfo = requestInfo;
865 * We expect the 'currentRepositorySession' member to be set only once per instance. Also, we expect only one open repository session
866 * per HTTP request. We'll log an error if we see more than one attempt to set a service context's current repo session.
868 * @see org.collectionspace.services.common.context.ServiceContext#setCurrentRepositorySession(java.lang.Object)
871 public void setCurrentRepositorySession(Object repoSession) throws Exception {
872 if (repoSession == null) {
873 String errMsg = "Setting a service context's repository session to null is not allowed.";
874 logger.error(errMsg);
875 throw new Exception(errMsg);
876 } else if (currentRepositorySession != null && currentRepositorySession != repoSession) {
877 String errMsg = "The current service context's repository session was replaced. This may cause unexpected behavior and/or data loss.";
878 logger.error(errMsg);
879 throw new Exception(errMsg);
882 currentRepositorySession = repoSession;
883 this.currentRepoSesssionRefCount++;
887 public void clearCurrentRepositorySession() {
888 if (this.currentRepoSesssionRefCount > 0) {
889 currentRepoSesssionRefCount--;
892 if (currentRepoSesssionRefCount == 0) {
893 this.currentRepositorySession = null;
898 public Object getCurrentRepositorySession() {
899 // TODO Auto-generated method stub
900 return currentRepositorySession;
904 public RepositoryDomainType getRepositoryDomain() {
905 return repositoryDomain;
909 public void setRepositoryDomain(RepositoryDomainType repositoryDomain) {
910 this.repositoryDomain = repositoryDomain;
914 * Check for a query parameter that indicates if we should force a sync even if the revision numbers indicate otherwise.
918 public boolean shouldForceSync() {
919 boolean forceSync = false;
921 MultivaluedMap<String, String> queryParams = getQueryParams();
922 String paramValue = queryParams.getFirst(IClientQueryParams.FORCE_SYCN);
923 if (paramValue != null && paramValue.equalsIgnoreCase(Boolean.TRUE.toString())) { // Find our if the caller wants us to force refname updates
925 } else if (paramValue != null && paramValue.equals(Long.toString(1))) {