/*
* 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:
* Thomas Roger
* Dragos Mihalache
* Florent Guillaume
*/
package org.eclipse.ecr.core.api.impl;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.ecr.core.api.ClientException;
import org.eclipse.ecr.core.api.CoreSession;
import org.eclipse.ecr.core.api.DataModel;
import org.eclipse.ecr.core.api.DataModelMap;
import org.eclipse.ecr.core.api.DocumentException;
import org.eclipse.ecr.core.api.DocumentModel;
import org.eclipse.ecr.core.api.DocumentRef;
import org.eclipse.ecr.core.api.Lock;
import org.eclipse.ecr.core.api.PathRef;
import org.eclipse.ecr.core.api.VersioningOption;
import org.eclipse.ecr.core.api.model.DocumentPart;
import org.eclipse.ecr.core.api.model.Property;
import org.eclipse.ecr.core.api.model.PropertyException;
import org.eclipse.ecr.core.api.model.PropertyNotFoundException;
import org.eclipse.ecr.core.api.model.impl.DefaultPropertyFactory;
import org.eclipse.ecr.core.api.security.ACP;
import org.eclipse.ecr.core.schema.DocumentType;
import org.eclipse.ecr.core.schema.SchemaManager;
import org.eclipse.ecr.core.schema.types.Schema;
import org.eclipse.ecr.runtime.api.Framework;
import org.nuxeo.common.collections.ScopeType;
import org.nuxeo.common.collections.ScopedMap;
import org.nuxeo.common.utils.Path;
/**
* A DocumentModel that can have any schema and is not made persistent by
* itself. A mockup to keep arbitrary schema data.
*/
public class SimpleDocumentModel implements DocumentModel {
private static final long serialVersionUID = 1L;
protected final boolean anySchema;
protected final DataModelMap dataModels = new DataModelMapImpl();
protected final ScopedMap contextData = new ScopedMap();
protected Path path;
protected String type;
public SimpleDocumentModel(List<String> schemas) {
for (String schema : schemas) {
dataModels.put(schema, new SimpleDataModel(schema));
}
anySchema = false;
}
public SimpleDocumentModel(String... schemas) {
this(Arrays.asList(schemas));
}
public SimpleDocumentModel() {
anySchema = true;
}
/**
* A data model that is not tied to a particular schema, neither has
* anything to do with a session (CoreSession).
*/
public static class SimpleDataModel implements DataModel {
private static final long serialVersionUID = 1L;
public final String schema;
public final Map<String, Object> data = new HashMap<String, Object>();
public SimpleDataModel(String schema) {
this.schema = schema;
}
@Override
public void setData(String key, Object value) throws PropertyException {
data.put(key, value);
}
@Override
public Object getData(String key) throws PropertyException {
return data.get(key);
}
@Override
public String getSchema() {
return schema;
}
@Override
public Map<String, Object> getMap() throws PropertyException {
return data;
}
@Override
public void setMap(Map<String, Object> data) throws PropertyException {
data = new HashMap<String, Object>(data);
}
@Override
public boolean isDirty() {
return true;
}
@Override
public boolean isDirty(String name) throws PropertyNotFoundException {
return true;
}
@Override
public void setDirty(String name) throws PropertyNotFoundException {
}
@Override
public Collection<String> getDirtyFields() {
return data.keySet();
}
@Override
public Object getValue(String path) throws PropertyException {
throw new UnsupportedOperationException("getValue");
}
@Override
public Object setValue(String path, Object value)
throws PropertyException {
throw new UnsupportedOperationException("setValue");
}
}
protected DataModel getDataModelInternal(String schema) {
DataModel dm = dataModels.get(schema);
if (dm == null && anySchema) {
dm = new SimpleDataModel(schema);
dataModels.put(schema, dm);
}
return dm;
}
@Override
public String[] getSchemas() {
Set<String> keys = dataModels.keySet();
return keys.toArray(new String[keys.size()]);
}
@Override
public String[] getDeclaredSchemas() {
return getSchemas();
}
@Override
public Object getProperty(String schemaName, String name)
throws ClientException {
DataModel dm = getDataModelInternal(schemaName);
return dm != null ? dm.getData(name) : null;
}
@Override
public void setProperty(String schemaName, String name, Object value)
throws ClientException {
if (name.contains(":")) {
name = name.substring(name.indexOf(":"), name.length());
}
getDataModelInternal(schemaName).setData(name, value);
}
@Override
public Map<String, Object> getProperties(String schemaName)
throws ClientException {
return getDataModelInternal(schemaName).getMap();
}
@Override
public void setProperties(String schemaName, Map<String, Object> data)
throws ClientException {
getDataModelInternal(schemaName).setMap(data);
}
@Override
public ScopedMap getContextData() {
return contextData;
}
@Override
public Serializable getContextData(ScopeType scope, String key) {
return contextData.getScopedValue(scope, key);
}
@Override
public void putContextData(ScopeType scope, String key, Serializable value) {
contextData.putScopedValue(scope, key, value);
}
@Override
public Serializable getContextData(String key) {
return contextData.getScopedValue(key);
}
@Override
public void putContextData(String key, Serializable value) {
contextData.putScopedValue(key, value);
}
@Override
public void copyContextData(DocumentModel otherDocument) {
ScopedMap otherMap = otherDocument.getContextData();
if (otherMap != null) {
contextData.putAll(otherMap);
}
}
@Override
public Property getProperty(String xpath) throws PropertyException,
ClientException {
Path path = new Path(xpath);
if (path.segmentCount() == 0) {
throw new PropertyNotFoundException(xpath, "Schema not specified");
}
String segment = path.segment(0);
int p = segment.indexOf(':');
if (p == -1) { // support also other schema paths? like schema.property
// allow also unprefixed schemas -> make a search for the first
// matching schema having a property with same name as path segment
// 0
DocumentPart[] parts = getParts();
for (DocumentPart part : parts) {
if (part.getSchema().hasField(segment)) {
return part.resolvePath(path.toString());
}
}
// could not find any matching schema
throw new PropertyNotFoundException(xpath, "Schema not specified");
}
String prefix = segment.substring(0, p);
SchemaManager mgr = Framework.getLocalService(SchemaManager.class);
Schema schema = mgr.getSchemaFromPrefix(prefix);
if (schema == null) {
schema = mgr.getSchema(prefix);
if (schema == null) {
throw new PropertyNotFoundException(xpath,
"Could not find registered schema with prefix: "
+ prefix);
}
}
String[] segments = path.segments();
segments[0] = segments[0].substring(p + 1);
path = Path.createFromSegments(segments);
DocumentPart part = DefaultPropertyFactory.newDocumentPart(schema);
part.init((Serializable) getDataModelInternal(schema.getName()).getMap());
return part.resolvePath(path.toString());
}
@Override
public Serializable getPropertyValue(String xpath)
throws PropertyException, ClientException {
return getProperty(xpath).getValue();
}
@Override
public void setPropertyValue(String xpath, Serializable value)
throws PropertyException, ClientException {
getProperty(xpath).setValue(value);
}
@Override
public DocumentType getDocumentType() {
throw new UnsupportedOperationException();
}
@Override
public String getSessionId() {
throw new UnsupportedOperationException();
}
@Override
public CoreSession getCoreSession() {
throw new UnsupportedOperationException();
}
@Override
public DocumentRef getRef() {
throw new UnsupportedOperationException();
}
@Override
public DocumentRef getParentRef() {
if (path == null) {
return null;
}
if (!path.isAbsolute()) {
return null;
}
return new PathRef(path.removeLastSegments(1).toString());
}
@Override
public String getId() {
throw new UnsupportedOperationException();
}
@Override
public String getName() {
return path == null ? null : path.lastSegment();
}
@Override
public String getPathAsString() {
return path == null ? null : path.toString();
}
@Override
public Path getPath() {
return path;
}
@Override
public String getTitle() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public Set<String> getFacets() {
throw new UnsupportedOperationException();
}
@Override
public Set<String> getDeclaredFacets() {
return getFacets();
}
@Override
public Collection<DataModel> getDataModelsCollection() {
throw new UnsupportedOperationException();
}
@Override
public DataModelMap getDataModels() {
return dataModels;
}
@Override
public DataModel getDataModel(String schema) throws ClientException {
return getDataModelInternal(schema);
}
@Override
public void setPathInfo(String parentPath, String name) {
throw new UnsupportedOperationException();
}
@Override
public String getLock() {
throw new UnsupportedOperationException();
}
@Override
public boolean isLocked() {
throw new UnsupportedOperationException();
}
@Override
public void setLock(String key) throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public void unlock() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public Lock setLock() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public Lock getLockInfo() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public Lock removeLock() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public ACP getACP() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public void setACP(ACP acp, boolean overwrite) throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public boolean hasSchema(String schema) {
throw new UnsupportedOperationException();
}
@Override
public boolean hasFacet(String facet) {
throw new UnsupportedOperationException();
}
@Override
public boolean addFacet(String facet) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeFacet(String facet) {
throw new UnsupportedOperationException();
}
@Override
public boolean isFolder() {
throw new UnsupportedOperationException();
}
@Override
public boolean isVersionable() {
throw new UnsupportedOperationException();
}
@Override
public boolean isDownloadable() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public boolean isVersion() {
throw new UnsupportedOperationException();
}
@Override
public boolean isProxy() {
throw new UnsupportedOperationException();
}
@Override
public boolean isImmutable() {
throw new UnsupportedOperationException();
}
@Override
public <T> T getAdapter(Class<T> itf) {
throw new UnsupportedOperationException();
}
@Override
public <T> T getAdapter(Class<T> itf, boolean refreshCache) {
throw new UnsupportedOperationException();
}
@Override
public String getCurrentLifeCycleState() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public String getLifeCyclePolicy() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public boolean followTransition(String transition) throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public Collection<String> getAllowedStateTransitions()
throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public void copyContent(DocumentModel sourceDoc) throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public String getRepositoryName() {
throw new UnsupportedOperationException();
}
@Override
public String getCacheKey() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public String getSourceId() {
throw new UnsupportedOperationException();
}
@Override
public String getVersionLabel() {
throw new UnsupportedOperationException();
}
@Override
public String getCheckinComment() {
throw new UnsupportedOperationException();
}
@Override
public Map<String, Serializable> getPrefetch() {
throw new UnsupportedOperationException();
}
@Override
public void prefetchProperty(String id, Object value) {
throw new UnsupportedOperationException();
}
@Override
public void prefetchCurrentLifecycleState(String lifecycle) {
throw new UnsupportedOperationException();
}
@Override
public void prefetchLifeCyclePolicy(String lifeCyclePolicy) {
throw new UnsupportedOperationException();
}
@Override
public boolean isLifeCycleLoaded() {
throw new UnsupportedOperationException();
}
@Override
public <T extends Serializable> T getSystemProp(String systemProperty,
Class<T> type) throws ClientException, DocumentException {
throw new UnsupportedOperationException();
}
@Override
public DocumentPart getPart(String schema) throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public DocumentPart[] getParts() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public long getFlags() {
throw new UnsupportedOperationException();
}
@Override
public void reset() {
throw new UnsupportedOperationException();
}
@Override
public void refresh(int refreshFlags, String[] schemas)
throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public void refresh() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public DocumentModel clone() throws CloneNotSupportedException {
throw new UnsupportedOperationException();
}
@Override
public boolean isCheckedOut() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public void checkOut() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public DocumentRef checkIn(VersioningOption option, String description)
throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public String getVersionSeriesId() throws ClientException {
throw new UnsupportedOperationException();
}
@Override
public boolean isLatestVersion() throws ClientException {
return false;
}
@Override
public boolean isMajorVersion() throws ClientException {
return false;
}
@Override
public boolean isLatestMajorVersion() throws ClientException {
return false;
}
@Override
public boolean isVersionSeriesCheckedOut() throws ClientException {
return true;
}
}