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