/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nuxeo - initial API and implementation * * $Id$ */ package org.eclipse.ecr.core.schema; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.eclipse.ecr.core.schema.types.CompositeTypeImpl; import org.eclipse.ecr.runtime.api.Framework; /** * Implementation of a document type. * <p> * This class uses lazy loading for schemas and field types. * <p> * Schemas and fields are cached to improve lookups time. * * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> */ public class DocumentTypeImpl extends CompositeTypeImpl implements DocumentType { public static final int T_DOCUMENT = 1 << 8; public static final int T_FOLDER = 2 << 8; public static final int T_ORDERED = 4 << 8; private static final long serialVersionUID = 4257192861843860742L; private static final String[] EMPTY_FACETS = {}; protected int unstructured; protected String[] declaredFacets = EMPTY_FACETS; protected Set<String> facets; protected String[] subtypes; protected PrefetchInfo prefetchInfo; public DocumentTypeImpl(DocumentType superType, String name) { this(superType == null ? null : superType.getRef(), name, null, null, 0); } public DocumentTypeImpl(DocumentType superType, String name, String[] declaredSchemas) { this(superType == null ? null : superType.getRef(), name, declaredSchemas, null, 0); } public DocumentTypeImpl(DocumentType superType, String name, String[] declaredSchemas, String[] declaredFacets) { this(superType == null ? null : superType.getRef(), name, declaredSchemas, declaredFacets, 0); } public DocumentTypeImpl(TypeRef<DocumentType> superType, String name) { this(superType, name, null, null, 0); } public DocumentTypeImpl(TypeRef<DocumentType> superType, String name, String[] declaredSchemas) { this (superType, name, declaredSchemas, null, 0); } public DocumentTypeImpl(TypeRef<DocumentType> superType, String name, String[] declaredSchemas, String[] facets) { this (superType, name, declaredSchemas, facets, 0); } public DocumentTypeImpl(TypeRef<DocumentType> superType, String name, String[] declaredSchemas, String[] facets, int flags) { super(superType, SchemaNames.DOCTYPES, name, declaredSchemas); if (flags != 0) { setFlags(flags); } else { DocumentType stype = (DocumentType) this.superType.get(); if (stype != null) { if (stype.isOrdered()) { setFlags(T_ORDERED | T_FOLDER); } else if (stype.isFolder()) { setFlags(T_FOLDER); } else { setFlags(T_DOCUMENT); } } else { setFlags(T_DOCUMENT); } } declaredFacets = facets == null ? EMPTY_FACETS : facets; subtypes = null; } @Override public void setPrefetchInfo(PrefetchInfo prefetchInfo) { this.prefetchInfo = prefetchInfo; } @Override public PrefetchInfo getPrefetchInfo() { return prefetchInfo; } @Override public boolean isUnstructured() { if (unstructured == F_UNSTRUCT_DEFAULT) { unstructured = hasSchemas() ? F_UNSTRUCT_FALSE : F_UNSTRUCT_TRUE; } return unstructured == F_UNSTRUCT_TRUE; } @Override public boolean isFile() { return !getFacets().contains(FacetNames.FOLDERISH); } @Override public boolean isFolder() { return getFacets().contains(FacetNames.FOLDERISH); } @Override public boolean isOrdered() { Set<String> facets = getFacets(); return facets.contains(FacetNames.ORDERABLE); //return isFolder() && isFlagSet(T_ORDERED | T_FOLDER); } @Override public Set<String> getFacets() { if (facets == null) { facets = buildFacets(); } return facets; } @Override public void addSchemas(String[] schemas) { if (schemas != null) { for (String schema : schemas) { addSchema(schema); } } } @Override public void setDeclaredFacets(String[] facets) { declaredFacets = facets == null ? EMPTY_FACETS : facets; this.facets = null; } protected Set<String> buildFacets() { Set<String> facets = new HashSet<String>(); DocumentTypeImpl stype = (DocumentTypeImpl) superType.get(); if (stype == null) { facets.addAll(Arrays.asList(declaredFacets)); } else { Set<String> inheritedFacets = stype.buildFacets(); if (declaredFacets.length == 0) { facets = inheritedFacets; } else { for (String facet : inheritedFacets) { facets.add(facet); } facets.addAll(Arrays.asList(declaredFacets)); } } return facets; } @Override public TypeRef<DocumentType> getRef() { return new TypeRef<DocumentType>(schema, name, this); } @Override public String[] getChildrenTypes() { return subtypes; } @Override public void setChildrenTypes(String[] subTypes) { subtypes = subTypes; } @Override public DocumentType[] getResolvedChildrenTypes() { SchemaManager mgr = Framework.getLocalService(SchemaManager.class); if (subtypes != null) { DocumentType[] result = new DocumentType[subtypes.length]; for (int i = 0; i < subtypes.length; i++) { result[i] = mgr.getDocumentType(subtypes[i]); } return result; } return null; } @Override public boolean isChildTypeAllowed(String name) { if (subtypes != null) { for (String subtype : subtypes) { if (subtype.equals(name)) { return true; } } // TODO: expand * return false; } return false; } }