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.lang3.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}.
044 */
045public class NuxeoCmisServiceFactory extends AbstractServiceFactory {
046
047    public static final String PROP_TEMP_DIRECTORY = "service.tempDirectory";
048
049    public static final String PROP_ENCRYPT_TEMP_FILES = "service.encryptTempFiles";
050
051    public static final String PROP_MEMORY_THERESHOLD = "service.memoryThreshold";
052
053    public static final String PROP_MAX_CONTENT_SIZE = "service.maxContentSize";
054
055    public static final String PROP_DEFAULT_TYPES_MAX_ITEMS = "service.defaultTypesMaxItems";
056
057    public static final String PROP_DEFAULT_TYPES_DEPTH = "service.defaultTypesDepth";
058
059    public static final String PROP_DEFAULT_MAX_ITEMS = "service.defaultMaxItems";
060
061    public static final String PROP_DEFAULT_DEPTH = "service.defaultDepth";
062
063    public static final int DEFAULT_TYPES_MAX_ITEMS = 100;
064
065    public static final int DEFAULT_TYPES_DEPTH = -1;
066
067    public static final int DEFAULT_MAX_ITEMS = 100;
068
069    public static final int DEFAULT_DEPTH = 2;
070
071    protected CmisServiceWrapperManager wrapperManager;
072
073    protected BigInteger defaultTypesMaxItems;
074
075    protected BigInteger defaultTypesDepth;
076
077    protected BigInteger defaultMaxItems;
078
079    protected BigInteger defaultDepth;
080
081    protected File tempDirectory;
082
083    protected boolean encryptTempFiles;
084
085    protected long memoryThreshold;
086
087    protected long maxContentSize;
088
089    @Override
090    public void init(Map<String, String> parameters) {
091        initParameters(parameters);
092        wrapperManager = new CmisServiceWrapperManager();
093        wrapperManager.addWrappersFromServiceFactoryParameters(parameters);
094        // wrap the service to provide default parameter checks
095        wrapperManager.addOuterWrapper(NuxeoCmisServiceWrapper.class, defaultTypesMaxItems, defaultTypesDepth,
096                defaultMaxItems, defaultDepth);
097    }
098
099    protected void initParameters(Map<String, String> parameters) {
100        String tempDirectoryStr = parameters.get(PROP_TEMP_DIRECTORY);
101        tempDirectory = StringUtils.isBlank(tempDirectoryStr) ? super.getTempDirectory() : new File(
102                tempDirectoryStr.trim());
103        String encryptTempStr = parameters.get(PROP_ENCRYPT_TEMP_FILES);
104        encryptTempFiles = StringUtils.isBlank(encryptTempStr) ? super.encryptTempFiles()
105                : Boolean.parseBoolean(encryptTempStr.trim());
106        memoryThreshold = getLongParameter(parameters, PROP_MEMORY_THERESHOLD, super.getMemoryThreshold());
107        maxContentSize = getLongParameter(parameters, PROP_MAX_CONTENT_SIZE, Long.MAX_VALUE);
108        defaultTypesMaxItems = getBigIntegerParameter(parameters, PROP_DEFAULT_TYPES_MAX_ITEMS, DEFAULT_TYPES_MAX_ITEMS);
109        defaultTypesDepth = getBigIntegerParameter(parameters, PROP_DEFAULT_TYPES_DEPTH, DEFAULT_TYPES_DEPTH);
110        defaultMaxItems = getBigIntegerParameter(parameters, PROP_DEFAULT_MAX_ITEMS, DEFAULT_MAX_ITEMS);
111        defaultDepth = getBigIntegerParameter(parameters, PROP_DEFAULT_DEPTH, DEFAULT_DEPTH);
112    }
113
114    protected static long getLongParameter(Map<String, String> parameters, String key, long def) {
115        String value = parameters.get(key);
116        try {
117            return StringUtils.isBlank(value) ? def : Long.parseLong(value);
118        } catch (NumberFormatException e) {
119            throw new CmisRuntimeException("Could not parse configuration values for " + key + ": " + e.getMessage(), e);
120        }
121    }
122
123    protected static BigInteger getBigIntegerParameter(Map<String, String> parameters, String key, int def) {
124        String value = parameters.get(key);
125        try {
126            return StringUtils.isBlank(value) ? BigInteger.valueOf(def) : new BigInteger(value);
127        } catch (NumberFormatException e) {
128            throw new CmisRuntimeException("Could not parse configuration values for " + key + ": " + e.getMessage(), e);
129        }
130    }
131
132    @Override
133    public CmisService getService(CallContext context) {
134        String repositoryId = context.getRepositoryId();
135        if (StringUtils.isBlank(repositoryId)) {
136            repositoryId = null;
137        } else {
138            NuxeoRepository repository = Framework.getService(NuxeoRepositories.class).getRepository(repositoryId);
139            if (repository == null) {
140                throw new CmisInvalidArgumentException("No such repository: " + repositoryId);
141            }
142        }
143        NuxeoCmisService nuxeoCmisService = new NuxeoCmisService(repositoryId);
144        CallContextAwareCmisService service = (CallContextAwareCmisService) wrapperManager.wrap(nuxeoCmisService);
145        service.setCallContext(context);
146        return service;
147    }
148
149    @Override
150    public File getTempDirectory() {
151        return tempDirectory;
152    }
153
154    @Override
155    public boolean encryptTempFiles() {
156        return encryptTempFiles;
157    }
158
159    @Override
160    public int getMemoryThreshold() {
161        return (int) memoryThreshold;
162    }
163
164    @Override
165    public long getMaxContentSize() {
166        return maxContentSize;
167    }
168
169}