// "readonly" meaningful for proxies and versions, used for import private Document newDocument(Node node, boolean readonly) { if (node == null) { // root's parent return null; } Node targetNode = null; String typeName = node.getPrimaryType(); if (node.isProxy()) { Serializable targetId = node.getSimpleProperty(Model.PROXY_TARGET_PROP).getValue(); if (targetId == null) { throw new NoSuchDocumentException("Proxy has null target"); } targetNode = session.getNodeById(targetId); typeName = targetNode.getPrimaryType(); } SchemaManager schemaManager = Framework.getLocalService(SchemaManager.class); DocumentType type = schemaManager.getDocumentType(typeName); if (type == null) { throw new NoSuchDocumentException("Unknown document type: " + typeName); } if (node.isProxy()) { // proxy seen as a normal document Document proxy = new SQLDocumentLive(node, type, this, false); Document target = newDocument(targetNode, readonly); return new SQLDocumentProxy(proxy, target); } else if (node.isVersion()) { return new SQLDocumentVersion(node, type, this, readonly); } else { return new SQLDocumentLive(node, type, this, false); } }
@Test public void testWithoutParent() throws Exception { DocumentType type = schemaManager.getDocumentType("Document"); JsonAssert json = jsonAssert(type); json.properties(5); json.has("parent").isNull(); }
/** Visits all the blobs of this document and calls the passed blob visitor on each one. */ protected void visitBlobs(T state, Consumer<BlobAccessor> blobVisitor, Runnable markDirty) throws PropertyException { Visit visit = new Visit(blobVisitor, markDirty); // structural type visit.visitBlobsComplex(state, getType()); // dynamic facets SchemaManager schemaManager = Framework.getService(SchemaManager.class); for (String facet : getFacets()) { CompositeType facetType = schemaManager.getFacet(facet); visit.visitBlobsComplex(state, facetType); } // proxy schemas if (getProxySchemas() != null) { for (Schema schema : getProxySchemas()) { visit.visitBlobsComplex(state, schema); } } }
public String[] getSuperTypes(String typeName) { try { SchemaManager schemaMgr = Framework.getService(SchemaManager.class); DocumentType type = schemaMgr.getDocumentType(typeName); if (type == null) { return null; } type = (DocumentType) type.getSuperType(); List<String> superTypes = new ArrayList<String>(); while (type != null) { superTypes.add(type.getName()); type = (DocumentType) type.getSuperType(); } return superTypes.toArray(new String[superTypes.size()]); } catch (Exception e) { log.error("Failed to lookup the SchemaManager service", e); return new String[0]; } }
@Test public void test() throws Exception { DocumentType type = schemaManager.getDocumentType("Folder"); JsonAssert json = jsonAssert(type); json.properties(5); json.has("entity-type").isEquals("docType"); json.has("name").isEquals("Folder"); json.has("parent").isEquals("Document"); json.has("facets").contains("Folderish"); json = json.has("schemas").length(2); json.childrenContains("entity-type", "schema", "schema"); json.childrenContains("name", "common", "dublincore"); }
@Test public void testDoctypesAvailability() throws ClientException { String[] doctypes = new String[] { Deliverable.DOCTYPE, DeployedDeliverable.DOCTYPE, Endpoint.DOCTYPE, IntelligentSystem.DOCTYPE, IntelligentSystemTreeRoot.DOCTYPE, Repository.DOCTYPE, InformationService.DOCTYPE, ServiceImplementation.DOCTYPE, SoftwareComponent.DOCTYPE, SystemTreeRoot.DOCTYPE, TaggingFolder.DOCTYPE }; for (String doctype : doctypes) { Assert.assertNotNull( "Doctype " + doctype + " must exist", schemaManager.getDocumentType(doctype)); } }
/** * Returns a schema, given the name of a schema. * * @param schemaName a schema name. * @return a schema. */ public static Schema getSchemaFromName(String schemaName) { SchemaManager schemaManager = Framework.getLocalService(SchemaManager.class); return schemaManager.getSchema(schemaName); }
/** Recomputes all the info needed for efficient access. */ private void recomputeSourceInfos() throws DirectoryException { final Schema schema = schemaManager.getSchema(schemaName); if (schema == null) { throw new DirectoryException( String.format("Directory '%s' has unknown schema '%s'", directory.getName(), schemaName)); } final Set<String> sourceFields = new HashSet<String>(); for (Field f : schema.getFields()) { sourceFields.add(f.getName().getLocalName()); } if (!sourceFields.contains(schemaIdField)) { throw new DirectoryException( String.format( "Directory '%s' schema '%s' has no id field '%s'", directory.getName(), schemaName, schemaIdField)); } List<SourceInfo> newSourceInfos = new ArrayList<SourceInfo>(2); for (SourceDescriptor source : descriptor.sources) { int ndirs = source.subDirectories.length; if (ndirs == 0) { throw new DirectoryException( String.format( "Directory '%s' source '%s' has no subdirectories", directory.getName(), source.name)); } final List<SubDirectoryInfo> subDirectoryInfos = new ArrayList<SubDirectoryInfo>(ndirs); SubDirectoryInfo authDirectoryInfo = null; boolean hasRequiredDir = false; for (SubDirectoryDescriptor subDir : source.subDirectories) { final String dirName = subDir.name; final String dirSchemaName = directoryService.getDirectorySchema(dirName); final String dirIdField = directoryService.getDirectoryIdField(dirName); final boolean dirIsAuth = directoryService.getDirectoryPasswordField(dirName) != null; final Map<String, String> fromSource = new HashMap<String, String>(); final Map<String, String> toSource = new HashMap<String, String>(); final Map<String, Serializable> defaultEntry = new HashMap<String, Serializable>(); final boolean dirIsOptional = subDir.isOptional; // XXX check authenticating final Schema dirSchema = schemaManager.getSchema(dirSchemaName); if (dirSchema == null) { throw new DirectoryException( String.format( "Directory '%s' source '%s' subdirectory '%s' " + "has unknown schema '%s'", directory.getName(), source.name, dirName, dirSchemaName)); } // record default field mappings if same name and record default // values final Set<String> dirSchemaFields = new HashSet<String>(); for (Field f : dirSchema.getFields()) { final String fieldName = f.getName().getLocalName(); dirSchemaFields.add(fieldName); if (sourceFields.contains(fieldName)) { // XXX check no duplicates! fromSource.put(fieldName, fieldName); toSource.put(fieldName, fieldName); } // XXX cast to Serializable defaultEntry.put(fieldName, (Serializable) f.getDefaultValue()); } // treat renamings // XXX id field ? for (FieldDescriptor field : subDir.fields) { final String sourceFieldName = field.forField; final String fieldName = field.name; if (!sourceFields.contains(sourceFieldName)) { throw new DirectoryException( String.format( "Directory '%s' source '%s' subdirectory '%s' " + "has mapping for unknown field '%s'", directory.getName(), source.name, dirName, sourceFieldName)); } if (!dirSchemaFields.contains(fieldName)) { throw new DirectoryException( String.format( "Directory '%s' source '%s' subdirectory '%s' " + "has mapping of unknown field' '%s'", directory.getName(), source.name, dirName, fieldName)); } fromSource.put(sourceFieldName, fieldName); toSource.put(fieldName, sourceFieldName); } SubDirectoryInfo subDirectoryInfo = new SubDirectoryInfo( dirName, dirSchemaName, dirIdField, dirIsAuth, fromSource, toSource, defaultEntry, dirIsOptional); subDirectoryInfos.add(subDirectoryInfo); if (dirIsAuth) { if (authDirectoryInfo != null) { throw new DirectoryException( String.format( "Directory '%s' source '%s' has two subdirectories " + "with a password field, '%s' and '%s'", directory.getName(), source.name, authDirectoryInfo.dirName, dirName)); } authDirectoryInfo = subDirectoryInfo; } if (!dirIsOptional) { hasRequiredDir = true; } } if (isAuthenticating() && authDirectoryInfo == null) { throw new DirectoryException( String.format( "Directory '%s' source '%s' has no subdirectory " + "with a password field", directory.getName(), source.name)); } if (!hasRequiredDir) { throw new DirectoryException( String.format( "Directory '%s' source '%s' only has optional subdirectories: " + "no directory can be used has a reference.", directory.getName(), source.name)); } newSourceInfos.add(new SourceInfo(source, subDirectoryInfos, authDirectoryInfo)); } sourceInfos = newSourceInfos; }
@Test public void documentManagementInTestCasesExample() throws ClientException { SchemaManager typeService = Framework.getLocalService(SchemaManager.class); DocumentType[] types = typeService.getDocumentTypes(); for (DocumentType type : types) { System.out.println(type.getName()); } DocumentModel mydoc = session.createDocumentModel("File"); // DocumentModel mydoc = session.createDocumentModel("/", "toto", // "File"); mydoc.setPathInfo("/", "toto"); mydoc.setPropertyValue("dc:title", "Toto"); mydoc = session.createDocument(mydoc); session.save(); DocumentModelList docs = session.query("SELECT * FROM Document WHERE dc:title = 'Toto'"); assertEquals(1, docs.size()); mydoc = docs.get(0); assertEquals("toto", mydoc.getName()); assertEquals("project", mydoc.getCurrentLifeCycleState()); for (String state : mydoc.getAllowedStateTransitions()) { System.out.println("Transition : " + state); } // session.followTransition(mydoc.getRef(), "approve"); mydoc.followTransition("approve"); mydoc.setPropertyValue("dc:description", "My Description"); mydoc = session.saveDocument(mydoc); session.save(); assertEquals("approved", mydoc.getCurrentLifeCycleState()); assertEquals("0.0", mydoc.getVersionLabel()); assertEquals(0, session.getVersions(mydoc.getRef()).size()); session.checkIn(mydoc.getRef(), VersioningOption.MINOR, ""); mydoc = session.getDocument(mydoc.getRef()); assertEquals("0.1", mydoc.getVersionLabel()); assertEquals(1, session.getVersions(mydoc.getRef()).size()); DocumentModel folder = session.createDocumentModel("/", "folder", "Folder"); folder.setPropertyValue("dc:title", "Folder"); folder = session.createDocument(folder); session.save(); assertEquals(0, session.getChildren(folder.getRef()).size()); session.publishDocument(mydoc, folder); assertEquals(1, session.getChildren(folder.getRef()).size()); DocumentModel folder2 = session.createDocumentModel("/", "folder2", "Folder"); folder2.setPropertyValue("dc:title", "Folder2"); folder2 = session.createDocument(folder2); session.save(); DocumentModel proxy = session.createProxy(mydoc.getRef(), folder2.getRef()); assertEquals("Toto", proxy.getPropertyValue("dc:title")); mydoc.setPropertyValue("dc:title", "Tutu"); session.saveDocument(mydoc); session.save(); proxy = session.getDocument(proxy.getRef()); assertEquals("Tutu", proxy.getPropertyValue("dc:title")); proxy.setPropertyValue("dc:title", "Tata"); session.saveDocument(proxy); session.save(); mydoc = session.getDocument(mydoc.getRef()); assertEquals("Tata", mydoc.getPropertyValue("dc:title")); }
/** Sets a value (may be complex/list) into the document at the given xpath. */ protected void setValueObject(T state, String xpath, Object value) throws PropertyException { xpath = canonicalXPath(xpath); String[] segments = xpath.split("/"); ComplexType parentType = getType(); for (int i = 0; i < segments.length; i++) { String segment = segments[i]; Field field = parentType.getField(segment); if (field == null && i == 0) { // check facets SchemaManager schemaManager = Framework.getService(SchemaManager.class); for (String facet : getFacets()) { CompositeType facetType = schemaManager.getFacet(facet); field = facetType.getField(segment); if (field != null) { break; } } } if (field == null && i == 0 && getProxySchemas() != null) { // check proxy schemas for (Schema schema : getProxySchemas()) { field = schema.getField(segment); if (field != null) { break; } } } if (field == null) { throw new PropertyNotFoundException(xpath, i == 0 ? null : "Unknown segment: " + segment); } String name = field.getName().getPrefixedName(); // normalize from segment Type type = field.getType(); // check if we have a complex list index in the next position if (i < segments.length - 1 && StringUtils.isNumeric(segments[i + 1])) { int index = Integer.parseInt(segments[i + 1]); i++; if (!type.isListType() || ((ListType) type).getFieldType().isSimpleType()) { throw new PropertyNotFoundException(xpath, "Cannot use index after segment: " + segment); } List<T> list = getChildAsList(state, name); if (index >= list.size()) { throw new PropertyNotFoundException(xpath, "Index out of bounds: " + index); } // find complex list state state = list.get(index); field = ((ListType) type).getField(); if (i == segments.length - 1) { // last segment setValueComplex(state, field, value); } else { // not last segment parentType = (ComplexType) field.getType(); } continue; } if (i == segments.length - 1) { // last segment setValueField(state, field, value); } else { // not last segment if (type.isSimpleType()) { // scalar throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else if (type.isComplexType()) { // complex property state = getChildForWrite(state, name, type); parentType = (ComplexType) type; } else { // list ListType listType = (ListType) type; if (listType.isArray()) { // array of scalars throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else { // complex list but next segment was not numeric throw new PropertyNotFoundException( xpath, "Missing list index after segment: " + segment); } } } } }
/** Gets a value (may be complex/list) from the document at the given xpath. */ protected Object getValueObject(T state, String xpath) throws PropertyException { xpath = canonicalXPath(xpath); String[] segments = xpath.split("/"); /* * During this loop state may become null if we read an uninitialized complex property (DBS), in that case the * code must treat it as reading uninitialized values for its children. */ ComplexType parentType = getType(); for (int i = 0; i < segments.length; i++) { String segment = segments[i]; Field field = parentType.getField(segment); if (field == null && i == 0) { // check facets SchemaManager schemaManager = Framework.getService(SchemaManager.class); for (String facet : getFacets()) { CompositeType facetType = schemaManager.getFacet(facet); field = facetType.getField(segment); if (field != null) { break; } } } if (field == null && i == 0 && getProxySchemas() != null) { // check proxy schemas for (Schema schema : getProxySchemas()) { field = schema.getField(segment); if (field != null) { break; } } } if (field == null) { throw new PropertyNotFoundException(xpath, i == 0 ? null : "Unknown segment: " + segment); } String name = field.getName().getPrefixedName(); // normalize from segment Type type = field.getType(); // check if we have a complex list index in the next position if (i < segments.length - 1 && StringUtils.isNumeric(segments[i + 1])) { int index = Integer.parseInt(segments[i + 1]); i++; if (!type.isListType() || ((ListType) type).getFieldType().isSimpleType()) { throw new PropertyNotFoundException(xpath, "Cannot use index after segment: " + segment); } List<T> list = state == null ? Collections.emptyList() : getChildAsList(state, name); if (index >= list.size()) { throw new PropertyNotFoundException(xpath, "Index out of bounds: " + index); } // find complex list state state = list.get(index); parentType = (ComplexType) ((ListType) type).getFieldType(); if (i == segments.length - 1) { // last segment return getValueComplex(state, parentType); } else { // not last segment continue; } } if (i == segments.length - 1) { // last segment return state == null ? null : getValueField(state, field); } else { // not last segment if (type.isSimpleType()) { // scalar throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else if (type.isComplexType()) { // complex property state = state == null ? null : getChild(state, name, type); // here state can be null (DBS), continue loop with it, meaning uninitialized for read parentType = (ComplexType) type; } else { // list ListType listType = (ListType) type; if (listType.isArray()) { // array of scalars throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment); } else { // complex list but next segment was not numeric throw new PropertyNotFoundException( xpath, "Missing list index after segment: " + segment); } } } } throw new AssertionError("not reached"); }