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.config;
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.Hashtable;
30 import java.util.List;
32 import org.collectionspace.services.common.service.ServiceBindingType;
33 import org.collectionspace.services.common.service.ServiceObjectType;
34 import org.collectionspace.services.common.tenant.RepositoryDomainType;
35 import org.collectionspace.services.common.tenant.TenantBindingType;
36 import org.collectionspace.services.common.tenant.TenantBindingConfig;
37 import org.collectionspace.services.common.types.PropertyItemType;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
42 * ServicesConfigReader reads service layer specific configuration
44 * $LastChangedRevision: $
47 public class TenantBindingConfigReaderImpl
48 extends AbstractConfigReaderImpl<List<TenantBindingType>> {
49 final private static String TENANT_BINDINGS_ERROR = "Tenant bindings error: ";
50 final private static String TENANT_BINDINGS_FILENAME = "tenant-bindings.xml";
51 final private static String TENANT_BINDINGS_ROOTDIRNAME = "tenants";
53 final Logger logger = LoggerFactory.getLogger(TenantBindingConfigReaderImpl.class);
54 private List<TenantBindingType> tenantBindingTypeList;
55 //tenant id, tenant binding
56 private Hashtable<String, TenantBindingType> tenantBindings =
57 new Hashtable<String, TenantBindingType>();
59 private Hashtable<String, RepositoryDomainType> domains =
60 new Hashtable<String, RepositoryDomainType>();
61 //tenant-qualified servicename, service binding
62 private Hashtable<String, ServiceBindingType> serviceBindings =
63 new Hashtable<String, ServiceBindingType>();
65 //tenant-qualified service object name to service name, service binding
66 private Hashtable<String, ServiceBindingType> docTypes =
67 new Hashtable<String, ServiceBindingType>();
70 public TenantBindingConfigReaderImpl(String serverRootDir) {
75 public String getFileName() {
76 return TENANT_BINDINGS_FILENAME;
79 protected File getTenantsRootDir() {
81 String tenantsRootPath = getConfigRootDir() + File.separator + TENANT_BINDINGS_ROOTDIRNAME;
82 File tenantsRootDir = new File(tenantsRootPath);
83 if (tenantsRootDir.exists() == true) {
84 result = tenantsRootDir;
85 logger.debug("Tenants home directory is: " + tenantsRootDir.getAbsolutePath()); //FIXME: REM - Add proper if (logger.isDebug() == true) check
87 logger.error("Tenants home directory is missing. Can't find: " + tenantsRootDir.getAbsolutePath()); //FIXME: REM - Add proper if (logger.isError() == true) check
93 public void read() throws Exception {
94 String tenantsRootPath = getTenantsRootDir().getAbsolutePath();
95 read(tenantsRootPath);
99 public void read(String tenantRootDirPath) throws Exception {
100 File tenantsRootDir = new File(tenantRootDirPath);
101 if (tenantsRootDir.exists() == false) {
102 throw new Exception("Cound not find tenant bindings root directory: " +
105 List<File> tenantDirs = getDirectories(tenantsRootDir);
106 tenantBindingTypeList = readTenantConfigs(tenantDirs);
108 for (TenantBindingType tenantBinding : tenantBindingTypeList) {
109 tenantBindings.put(tenantBinding.getId(), tenantBinding);
110 readDomains(tenantBinding);
111 readServiceBindings(tenantBinding);
112 if (logger.isDebugEnabled()) {
113 logger.debug("read() added tenant id=" + tenantBinding.getId()
114 + " name=" + tenantBinding.getName());
119 List<TenantBindingType> readTenantConfigs(List<File> tenantDirList) throws IOException {
120 List<TenantBindingType> result = new ArrayList<TenantBindingType>();
122 // Iterate through a list of directories.
124 for (File tenantDir : tenantDirList) {
125 boolean found = false;
126 String errMessage = null;
127 File configFile = new File(tenantDir.getAbsoluteFile() + File.separator + TENANT_BINDINGS_FILENAME);
128 if (configFile.exists() == true) {
129 TenantBindingConfig tenantBindingConfig = (TenantBindingConfig) parse(
130 configFile, TenantBindingConfig.class);
131 if (tenantBindingConfig != null) {
132 TenantBindingType binding = tenantBindingConfig.getTenantBinding();
133 if (binding != null) {
136 if (logger.isInfoEnabled() == true) {
137 logger.info("Parsed tenant configureation for: " + binding.getDisplayName());
140 errMessage = "Cound not parse the tentant bindings in: ";
143 errMessage = "Could not parse the tenant bindings file: ";
146 errMessage = "Cound not find a tenant configuration file: ";
148 if (found == false) {
149 if (logger.isErrorEnabled() == true) {
150 errMessage = errMessage != null ? errMessage : TENANT_BINDINGS_ERROR;
151 logger.error(errMessage + configFile.getAbsolutePath());
159 private void readDomains(TenantBindingType tenantBinding) throws Exception {
160 for (RepositoryDomainType domain : tenantBinding.getRepositoryDomain()) {
161 domains.put(domain.getName(), domain);
165 private void readServiceBindings(TenantBindingType tenantBinding) throws Exception {
166 for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
167 String key = getTenantQualifiedServiceName(tenantBinding.getId(),
168 serviceBinding.getName());
169 serviceBindings.put(key, serviceBinding);
171 if (serviceBinding!=null){
172 ServiceObjectType objectType = serviceBinding.getObject();
173 if (objectType!=null){
174 String docType = objectType.getName();
175 String docTypeKey = getTenantQualifiedIdentifier(tenantBinding.getId(), docType);
176 docTypes.put(docTypeKey, serviceBinding);
179 if (logger.isDebugEnabled()) {
180 logger.debug("readServiceBindings() added service "
182 + " workspace=" + serviceBinding.getName());
188 public List<TenantBindingType> getConfiguration() {
189 return tenantBindingTypeList;
193 * getTenantBindings returns all the tenant bindings read from configuration
196 public Hashtable<String, TenantBindingType> getTenantBindings() {
197 return tenantBindings;
201 * getTenantBinding gets tenant binding for given tenant
205 public TenantBindingType getTenantBinding(
207 return tenantBindings.get(tenantId);
211 * getRepositoryDomain gets repository domain configuration for the given name
215 public RepositoryDomainType getRepositoryDomain(String domainName) {
216 return domains.get(domainName.trim());
220 * getRepositoryDomain gets repository domain configuration for the given service
221 * and given tenant id
226 public RepositoryDomainType getRepositoryDomain(String tenantId, String serviceName) {
227 ServiceBindingType serviceBinding = getServiceBinding(tenantId, serviceName);
228 if (serviceBinding == null) {
229 throw new IllegalArgumentException("no service binding found for " + serviceName
230 + " of tenant with id=" + tenantId);
232 String repoDomain = serviceBinding.getRepositoryDomain();
233 if (repoDomain == null) {
234 /* This is excessive - every call to a JPA based service dumps this msg.
235 if (logger.isDebugEnabled()) {
236 logger.debug("No repository domain configured for " + serviceName
237 + " of tenant with id=" + tenantId);
242 return domains.get(repoDomain.trim());
246 * getServiceBinding gets service binding for given tenant for a given service
251 public ServiceBindingType getServiceBinding(
252 String tenantId, String serviceName) {
253 String key = getTenantQualifiedServiceName(tenantId, serviceName);
254 return serviceBindings.get(key);
258 * getServiceBinding gets service binding for given tenant for a given service
263 public ServiceBindingType getServiceBindingForDocType (String tenantId, String docType) {
264 String key = getTenantQualifiedIdentifier(tenantId, docType);
265 return docTypes.get(key);
269 * getServiceBinding gets service binding for given tenant for a given service
274 public List<ServiceBindingType> getServiceBindingsByType(
275 String tenantId, String serviceType) {
276 ArrayList<ServiceBindingType> list = null;
277 TenantBindingType tenant = tenantBindings.get(tenantId);
278 if (tenant != null) {
279 for (ServiceBindingType sb : tenant.getServiceBindings()) {
280 if (serviceType.equals(sb.getType())) {
282 list = new ArrayList<ServiceBindingType>();
294 * @return the properly qualified service name
296 public static String getTenantQualifiedServiceName(
297 String tenantId, String serviceName) {
298 return tenantId + "." + serviceName.toLowerCase();
301 public static String getTenantQualifiedIdentifier(String tenantId, String identifier) {
302 return tenantId + "." + identifier;
305 * Sets properties in the passed list on the local properties for this TenantBinding.
306 * Note: will only set properties not already set on the TenantBinding.
309 * @param propagateToServices If true, recurses to set set properties
310 * on the associated services.
312 public void setDefaultPropertiesOnTenants(List<PropertyItemType> propList,
313 boolean propagateToServices) {
314 // For each tenant, set properties in list that are not already set
315 if (propList == null || propList.isEmpty()) {
318 for (TenantBindingType tenant : tenantBindings.values()) {
319 for (PropertyItemType prop : propList) {
320 TenantBindingUtils.setPropertyValue(tenant,
321 prop, TenantBindingUtils.SET_PROP_IF_MISSING);
323 if (propagateToServices) {
324 TenantBindingUtils.propagatePropertiesToServices(tenant,
325 TenantBindingUtils.SET_PROP_IF_MISSING);
330 public String getResourcesDir(){
331 return getConfigRootDir() + File.separator + "resources";