blob: b73baa23f87c955326e6ad5b5126269c70b2ecfc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.chemistry.opencmis.fileshare;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.chemistry.opencmis.commons.definitions.MutableDocumentTypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.MutableFolderTypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.MutablePropertyDefinition;
import org.apache.chemistry.opencmis.commons.definitions.MutableTypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.impl.IOUtils;
import org.apache.chemistry.opencmis.commons.impl.XMLConverter;
import org.apache.chemistry.opencmis.commons.impl.XMLUtils;
import org.apache.chemistry.opencmis.commons.server.CallContext;
import org.apache.chemistry.opencmis.server.support.TypeDefinitionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manages the type definitions for all FileShare repositories.
*/
public class FileShareTypeManager {
private static final Logger LOG = LoggerFactory.getLogger(FileShareTypeManager.class);
private static final String NAMESPACE = "http://chemistry.apache.org/opencmis/fileshare";
private final TypeDefinitionFactory typeDefinitionFactory;
private final Map<String, TypeDefinition> typeDefinitions;
public FileShareTypeManager() {
// set up TypeDefinitionFactory
typeDefinitionFactory = TypeDefinitionFactory.newInstance();
typeDefinitionFactory.setDefaultNamespace(NAMESPACE);
typeDefinitionFactory.setDefaultControllableAcl(false);
typeDefinitionFactory.setDefaultControllablePolicy(false);
typeDefinitionFactory.setDefaultQueryable(false);
typeDefinitionFactory.setDefaultFulltextIndexed(false);
typeDefinitionFactory.setDefaultTypeMutability(typeDefinitionFactory.createTypeMutability(false, false, false));
// set up definitions map
typeDefinitions = new HashMap<String, TypeDefinition>();
// add base folder type
MutableFolderTypeDefinition folderType = typeDefinitionFactory
.createBaseFolderTypeDefinition(CmisVersion.CMIS_1_1);
removeQueryableAndOrderableFlags(folderType);
typeDefinitions.put(folderType.getId(), folderType);
// add base document type
MutableDocumentTypeDefinition documentType = typeDefinitionFactory
.createBaseDocumentTypeDefinition(CmisVersion.CMIS_1_1);
removeQueryableAndOrderableFlags(documentType);
typeDefinitions.put(documentType.getId(), documentType);
}
/**
* Adds a type definition.
*/
public synchronized void addTypeDefinition(TypeDefinition type) {
if (type == null) {
throw new IllegalArgumentException("Type must be set!");
}
if (type.getId() == null || type.getId().trim().length() == 0) {
throw new IllegalArgumentException("Type must have a valid id!");
}
if (type.getParentTypeId() == null || type.getParentTypeId().trim().length() == 0) {
throw new IllegalArgumentException("Type must have a valid parent id!");
}
TypeDefinition parentType = typeDefinitions.get(type.getParentTypeId());
if (parentType == null) {
throw new IllegalArgumentException("Parent type doesn't exist!");
}
MutableTypeDefinition newType = typeDefinitionFactory.copy(type, true);
// copy parent type property definitions and mark them as inherited
for (PropertyDefinition<?> propDef : parentType.getPropertyDefinitions().values()) {
MutablePropertyDefinition<?> basePropDef = typeDefinitionFactory.copy(propDef);
basePropDef.setIsInherited(true);
newType.addPropertyDefinition(basePropDef);
}
typeDefinitions.put(newType.getId(), newType);
if (LOG.isDebugEnabled()) {
LOG.debug("Added type '{}'.", type.getId());
}
}
/**
* Removes the queryable and orderable flags from the property definitions
* of a type definition because this implementations does neither support
* queries nor can order objects.
*/
private void removeQueryableAndOrderableFlags(MutableTypeDefinition type) {
for (PropertyDefinition<?> propDef : type.getPropertyDefinitions().values()) {
MutablePropertyDefinition<?> mutablePropDef = (MutablePropertyDefinition<?>) propDef;
mutablePropDef.setIsQueryable(false);
mutablePropDef.setIsOrderable(false);
}
}
public void loadTypeDefinitionFromFile(String filename) throws IOException, XMLStreamException {
loadTypeDefinitionFromStream(new BufferedInputStream(new FileInputStream(filename), 64 * 1024));
}
public void loadTypeDefinitionFromResource(String name) throws IOException, XMLStreamException {
loadTypeDefinitionFromStream(this.getClass().getResourceAsStream(name));
}
public void loadTypeDefinitionFromStream(InputStream stream) throws IOException, XMLStreamException {
if (stream == null) {
throw new IllegalArgumentException("Stream is null!");
}
TypeDefinition type = null;
XMLStreamReader parser = null;
try {
parser = XMLUtils.createParser(stream);
if (!XMLUtils.findNextStartElemenet(parser)) {
return;
}
type = XMLConverter.convertTypeDefinition(parser);
} finally {
if (parser != null) {
parser.close();
}
IOUtils.closeQuietly(stream);
}
addTypeDefinition(type);
}
/**
* Returns the internal type definition.
*/
public synchronized TypeDefinition getInternalTypeDefinition(String typeId) {
return typeDefinitions.get(typeId);
}
/**
* Returns all internal type definitions.
*/
public synchronized Collection<TypeDefinition> getInternalTypeDefinitions() {
return typeDefinitions.values();
}
// --- service methods ---
public TypeDefinition getTypeDefinition(CallContext context, String typeId) {
TypeDefinition type = typeDefinitions.get(typeId);
if (type == null) {
throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
}
return typeDefinitionFactory.copy(type, true, context.getCmisVersion());
}
public TypeDefinitionList getTypeChildren(CallContext context, String typeId, Boolean includePropertyDefinitions,
BigInteger maxItems, BigInteger skipCount) {
return typeDefinitionFactory.createTypeDefinitionList(typeDefinitions, typeId, includePropertyDefinitions,
maxItems, skipCount, context.getCmisVersion());
}
public List<TypeDefinitionContainer> getTypeDescendants(CallContext context, String typeId, BigInteger depth,
Boolean includePropertyDefinitions) {
return typeDefinitionFactory.createTypeDescendants(typeDefinitions, typeId, depth, includePropertyDefinitions,
context.getCmisVersion());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (TypeDefinition type : typeDefinitions.values()) {
sb.append('[');
sb.append(type.getId());
sb.append(" (");
sb.append(type.getBaseTypeId().value());
sb.append(")]");
}
return sb.toString();
}
}