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