/* * Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * Licensed 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. */ package org.wso2.carbon.registry.cmis; import org.apache.axis2.AxisFault; import org.apache.catalina.connector.RequestFacade; import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; import org.apache.chemistry.opencmis.commons.impl.server.AbstractServiceFactory; import org.apache.chemistry.opencmis.commons.server.CallContext; import org.apache.chemistry.opencmis.commons.server.CmisService; import org.apache.chemistry.opencmis.commons.server.CmisServiceFactory; import org.apache.chemistry.opencmis.server.support.CmisServiceWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.wso2.carbon.registry.cmis.util.UserInfo; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.cmis.impl.DocumentTypeHandler; import org.wso2.carbon.registry.cmis.impl.FolderTypeHandler; import org.wso2.carbon.registry.cmis.impl.UnversionedDocumentTypeHandler; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.session.UserRegistry; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import java.math.BigInteger; import java.util.*; /** * A {@link CmisServiceFactory} implementation which returns {@link RegistryService} instances. */ public class CMISServiceFactory extends AbstractServiceFactory { private static final Logger log = LoggerFactory.getLogger(CMISServiceFactory.class); //The values should match the keys in repository.properties public static final String CARBON_HOME = "carbon-home"; public static final String TRUST_STORE = "trustStore"; public static final String AXIS2_REPO = "axis2repo"; public static final String AXIS2_CONF = "axis2Conf"; public static final String SERVER_URL = "serverUrl"; public static final BigInteger DEFAULT_MAX_ITEMS_TYPES = BigInteger.valueOf(50); public static final BigInteger DEFAULT_DEPTH_TYPES = BigInteger.valueOf(-1); public static final BigInteger DEFAULT_MAX_ITEMS_OBJECTS = BigInteger.valueOf(200); public static final BigInteger DEFAULT_DEPTH_OBJECTS = BigInteger.valueOf(10); private static final String uriPart = "/cmis/atom/WSO2%20CMIS%20Repository/content/"; private RegistryTypeManager typeManager; private PathManager pathManager; private Map<String, String> gregConfig; private String mountPath = "/"; private CMISRepository gregRepository; private Map<UserInfo, CMISRepository> sessions = Collections.synchronizedMap(new HashMap<UserInfo,CMISRepository>()); @Override public void init(Map<String, String> parameters) { //Read Configuration sets the gregConfig map readConfiguration(parameters); typeManager = createTypeManager(); pathManager = new PathManager(); DocumentTypeHandler documentTypeHandler = new DocumentTypeHandler(null, pathManager, typeManager); FolderTypeHandler folderTypeHandler = new FolderTypeHandler(null, pathManager, typeManager); UnversionedDocumentTypeHandler unversionedDocumentTypeHandler = new UnversionedDocumentTypeHandler(null, pathManager, typeManager); typeManager.addType(documentTypeHandler.getTypeDefinition()); typeManager.addType(folderTypeHandler.getTypeDefinition()); typeManager.addType(unversionedDocumentTypeHandler.getTypeDefinition()); } @Override public void destroy() { gregRepository = null; typeManager = null; } @Override public CmisService getService(CallContext context) { //Called for each service request, context contains username, password etc. //The registry clients are stored in the map "sessions" //If there is an existing session, use it. Otherwise make a new one. CMISRepository repository = null; //String username = "test"; String ip = ((RequestFacade)context.get(context.HTTP_SERVLET_REQUEST)).getRemoteAddr(); String url = ((RequestFacade)context.get(context.HTTP_SERVLET_REQUEST)).getRequestURL().toString(); String tenant = MultitenantUtils.getTenantDomain((RequestFacade)context.get(context.HTTP_SERVLET_REQUEST)); String username = context.getUsername(); if (username != null) { username = MultitenantUtils.getTenantAwareUsername(username); } UserInfo userInfoObj = new UserInfo(ip, username, tenant); if(url.contains(uriPart)) { repository = getRepo(userInfoObj); if (repository == null) throw new CmisRuntimeException("User is not authenticated to the repository to view the content"); } else if(sessions.containsKey(userInfoObj)) { repository = sessions.get(userInfoObj); //TODO check for session timeout } else { try { repository = new CMISRepository(acquireGregRepository(context, tenant, username), pathManager, typeManager); //put to sessions for future reference sessions.put(new UserInfo(ip, username, tenant), repository); } catch (RegistryException e) { e.printStackTrace(); throw new CmisRuntimeException(e.getMessage(), e); } catch (AxisFault axisFault) { axisFault.printStackTrace(); throw new CmisRuntimeException(axisFault.getMessage()); } } CmisServiceWrapper<CMISService> serviceWrapper = new CmisServiceWrapper<CMISService>( createGregService(repository, context), DEFAULT_MAX_ITEMS_TYPES, DEFAULT_DEPTH_TYPES, DEFAULT_MAX_ITEMS_OBJECTS, DEFAULT_DEPTH_OBJECTS); serviceWrapper.getWrappedService().setCallContext(context); return serviceWrapper; } /** * * @return result whether a given user is authorized to view the content from URL */ private CMISRepository getRepo (UserInfo obj) { boolean result = false; CMISRepository repo = null; for (UserInfo uInfo : sessions.keySet()) { if (uInfo.getIp().equals(obj.getIp()) && uInfo.getTenantDomain().equals(obj.getTenantDomain())) { repo = sessions.get(uInfo); break; } } return repo; } /** * @param context context with user data * @return * @throws org.wso2.carbon.registry.core.exceptions.RegistryException */ private Registry acquireGregRepository(CallContext context, String tenantDomain, String uName) throws RegistryException, AxisFault { UserRegistry userRegistry = null; try{ PrivilegedCarbonContext.getThreadLocalCarbonContext().startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); RegistryService registryService = (RegistryService) PrivilegedCarbonContext.getThreadLocalCarbonContext().getOSGiService(RegistryService.class); //userRegistry = registryService.getRegistry(username, password); userRegistry = registryService.getRegistry(uName, context.getPassword(), PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); } catch (RegistryException e) { log.error("unable to create registry instance for the respective enduser", e); } finally { PrivilegedCarbonContext.getThreadLocalCarbonContext().endTenantFlow(); } return userRegistry; } /** * Create a <code>org.wso2.registry.chemistry.greg.GregService</code> from a <code>org.wso2.registry.chemistry.greg.GregRepository</code>org.wso2.registry.chemistry.greg.GregRepository> and * <code>CallContext</code>. * * @param gregRepository * @param context * @return */ protected CMISService createGregService(CMISRepository gregRepository, CallContext context) { return new CMISService(gregRepository); } protected RegistryTypeManager createTypeManager() { return new RegistryTypeManager(); } private void readConfiguration(Map<String, String> parameters) { Map<String, String> map = new HashMap<String, String>(); List<String> keys = new ArrayList<String>(parameters.keySet()); Collections.sort(keys); map.put(CARBON_HOME, parameters.get(CARBON_HOME)); map.put(TRUST_STORE, parameters.get(TRUST_STORE)); map.put(AXIS2_REPO, parameters.get(AXIS2_REPO)); map.put(AXIS2_CONF, parameters.get(AXIS2_CONF)); map.put(SERVER_URL, parameters.get(SERVER_URL)); gregConfig = Collections.unmodifiableMap(map); //log.debug("Configuration: greg=" + gregConfig); } }