001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.opencmis.bindings;
020
021import java.io.File;
022import java.math.BigInteger;
023import java.util.Map;
024
025import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
026import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
027import org.apache.chemistry.opencmis.commons.impl.server.AbstractServiceFactory;
028import org.apache.chemistry.opencmis.commons.server.CallContext;
029import org.apache.chemistry.opencmis.commons.server.CmisService;
030import org.apache.chemistry.opencmis.server.support.wrapper.CallContextAwareCmisService;
031import org.apache.chemistry.opencmis.server.support.wrapper.CmisServiceWrapperManager;
032import org.apache.chemistry.opencmis.server.support.wrapper.ConformanceCmisServiceWrapper;
033import org.apache.commons.lang.StringUtils;
034import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
035import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepositories;
036import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepository;
037import org.nuxeo.runtime.api.Framework;
038
039/**
040 * Factory for a wrapped {@link NuxeoCmisService}.
041 * <p>
042 * Called for each method dispatch by {@link org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet} or
043 * {@link org.apache.chemistry.opencmis.server.impl.atompub.CmisBrowserBindingServlet} or
044 * {@link org.apache.chemistry.opencmis.server.impl.webservices.AbstractService}.
045 */
046public class NuxeoCmisServiceFactory extends AbstractServiceFactory {
047
048    public static final String PROP_TEMP_DIRECTORY = "service.tempDirectory";
049
050    public static final String PROP_ENCRYPT_TEMP_FILES = "service.encryptTempFiles";
051
052    public static final String PROP_MEMORY_THERESHOLD = "service.memoryThreshold";
053
054    public static final String PROP_MAX_CONTENT_SIZE = "service.maxContentSize";
055
056    public static final String PROP_DEFAULT_TYPES_MAX_ITEMS = "service.defaultTypesMaxItems";
057
058    public static final String PROP_DEFAULT_TYPES_DEPTH = "service.defaultTypesDepth";
059
060    public static final String PROP_DEFAULT_MAX_ITEMS = "service.defaultMaxItems";
061
062    public static final String PROP_DEFAULT_DEPTH = "service.defaultDepth";
063
064    public static final int DEFAULT_TYPES_MAX_ITEMS = 100;
065
066    public static final int DEFAULT_TYPES_DEPTH = -1;
067
068    public static final int DEFAULT_MAX_ITEMS = 100;
069
070    public static final int DEFAULT_DEPTH = 2;
071
072    protected CmisServiceWrapperManager wrapperManager;
073
074    protected BigInteger defaultTypesMaxItems;
075
076    protected BigInteger defaultTypesDepth;
077
078    protected BigInteger defaultMaxItems;
079
080    protected BigInteger defaultDepth;
081
082    protected File tempDirectory;
083
084    protected boolean encryptTempFiles;
085
086    protected long memoryThreshold;
087
088    protected long maxContentSize;
089
090    @Override
091    public void init(Map<String, String> parameters) {
092        initParameters(parameters);
093        wrapperManager = new CmisServiceWrapperManager();
094        wrapperManager.addWrappersFromServiceFactoryParameters(parameters);
095        // wrap the service to provide default parameter checks
096        wrapperManager.addOuterWrapper(NuxeoCmisServiceWrapper.class, defaultTypesMaxItems, defaultTypesDepth,
097                defaultMaxItems, defaultDepth);
098    }
099
100    protected void initParameters(Map<String, String> parameters) {
101        String tempDirectoryStr = parameters.get(PROP_TEMP_DIRECTORY);
102        tempDirectory = StringUtils.isBlank(tempDirectoryStr) ? super.getTempDirectory() : new File(
103                tempDirectoryStr.trim());
104        String encryptTempStr = parameters.get(PROP_ENCRYPT_TEMP_FILES);
105        encryptTempFiles = StringUtils.isBlank(encryptTempStr) ? super.encryptTempFiles()
106                : Boolean.parseBoolean(encryptTempStr.trim());
107        memoryThreshold = getLongParameter(parameters, PROP_MEMORY_THERESHOLD, super.getMemoryThreshold());
108        maxContentSize = getLongParameter(parameters, PROP_MAX_CONTENT_SIZE, Long.MAX_VALUE);
109        defaultTypesMaxItems = getBigIntegerParameter(parameters, PROP_DEFAULT_TYPES_MAX_ITEMS, DEFAULT_TYPES_MAX_ITEMS);
110        defaultTypesDepth = getBigIntegerParameter(parameters, PROP_DEFAULT_TYPES_DEPTH, DEFAULT_TYPES_DEPTH);
111        defaultMaxItems = getBigIntegerParameter(parameters, PROP_DEFAULT_MAX_ITEMS, DEFAULT_MAX_ITEMS);
112        defaultDepth = getBigIntegerParameter(parameters, PROP_DEFAULT_DEPTH, DEFAULT_DEPTH);
113    }
114
115    protected static long getLongParameter(Map<String, String> parameters, String key, long def) {
116        String value = parameters.get(key);
117        try {
118            return StringUtils.isBlank(value) ? def : Long.parseLong(value);
119        } catch (NumberFormatException e) {
120            throw new CmisRuntimeException("Could not parse configuration values for " + key + ": " + e.getMessage(), e);
121        }
122    }
123
124    protected static BigInteger getBigIntegerParameter(Map<String, String> parameters, String key, int def) {
125        String value = parameters.get(key);
126        try {
127            return StringUtils.isBlank(value) ? BigInteger.valueOf(def) : new BigInteger(value);
128        } catch (NumberFormatException e) {
129            throw new CmisRuntimeException("Could not parse configuration values for " + key + ": " + e.getMessage(), e);
130        }
131    }
132
133    @Override
134    public CmisService getService(CallContext context) {
135        String repositoryId = context.getRepositoryId();
136        if (StringUtils.isBlank(repositoryId)) {
137            repositoryId = null;
138        } else {
139            NuxeoRepository repository = Framework.getService(NuxeoRepositories.class).getRepository(repositoryId);
140            if (repository == null) {
141                throw new CmisInvalidArgumentException("No such repository: " + repositoryId);
142            }
143        }
144        NuxeoCmisService nuxeoCmisService = new NuxeoCmisService(repositoryId);
145        CallContextAwareCmisService service = (CallContextAwareCmisService) wrapperManager.wrap(nuxeoCmisService);
146        service.setCallContext(context);
147        return service;
148    }
149
150    @Override
151    public File getTempDirectory() {
152        return tempDirectory;
153    }
154
155    @Override
156    public boolean encryptTempFiles() {
157        return encryptTempFiles;
158    }
159
160    @Override
161    public int getMemoryThreshold() {
162        return (int) memoryThreshold;
163    }
164
165    @Override
166    public long getMaxContentSize() {
167        return maxContentSize;
168    }
169
170}