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 *     Nuxeo - initial API and implementation
011 *
012 * $Id$
013 */
014
015package org.nuxeo.ecm.core.api.impl;
016
017import java.io.Serializable;
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.Map;
022
023import org.nuxeo.ecm.core.api.DataModel;
024import org.nuxeo.ecm.core.api.PropertyException;
025import org.nuxeo.ecm.core.api.model.DocumentPart;
026import org.nuxeo.ecm.core.api.model.Property;
027import org.nuxeo.ecm.core.api.model.PropertyNotFoundException;
028import org.nuxeo.ecm.core.api.model.impl.AbstractProperty;
029import org.nuxeo.ecm.core.api.model.impl.DocumentPartImpl;
030import org.nuxeo.ecm.core.schema.SchemaManager;
031import org.nuxeo.ecm.core.schema.types.Schema;
032import org.nuxeo.runtime.api.Framework;
033
034/**
035 * Data model implementation.
036 *
037 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
038 */
039public class DataModelImpl implements DataModel {
040
041    private static final long serialVersionUID = 1L;
042
043    private final DocumentPart dp;
044
045    /**
046     * Builds an empty data model.
047     *
048     * @param schema a schema name.
049     */
050    public DataModelImpl(String schema) {
051        this(schema, new HashMap<String, Object>());
052    }
053
054    /**
055     * Builds a data model using the given data.
056     *
057     * @param schema a schema name.
058     * @param data the data (map String&gt;Object) to put in the DataModel.
059     */
060    public DataModelImpl(String schemaName, Map<String, Object> data) {
061        assert data != null;
062        SchemaManager schemaManager = Framework.getLocalService(SchemaManager.class);
063        Schema schema = schemaManager.getSchema(schemaName);
064        dp = new DocumentPartImpl(schema);
065        if (!data.isEmpty()) {
066            dp.init((Serializable) data);
067        }
068    }
069
070    public DataModelImpl(DocumentPart part) {
071        assert part != null;
072        dp = part;
073    }
074
075    /**
076     * Gets the underlying document part.
077     */
078    public DocumentPart getDocumentPart() {
079        return dp;
080    }
081
082    @Override
083    public String getSchema() {
084        return dp.getSchema().getName();
085    }
086
087    @Override
088    public Object getData(String key) throws PropertyException {
089        return dp.getValue(key);
090    }
091
092    @Override
093    public void setData(String key, Object value) throws PropertyException {
094        dp.setValue(key, value);
095    }
096
097    @Override
098    @SuppressWarnings("unchecked")
099    public Map<String, Object> getMap() throws PropertyException {
100        return (Map<String, Object>) dp.getValue();
101    }
102
103    @Override
104    public void setMap(Map<String, Object> data) throws PropertyException {
105        dp.setValue(data);
106    }
107
108    @Override
109    public boolean isDirty() {
110        return dp.isDirty();
111    }
112
113    @Override
114    public boolean isDirty(String name) throws PropertyNotFoundException {
115        return dp.get(name).isDirty();
116    }
117
118    @Override
119    public Collection<String> getDirtyFields() {
120        Collection<String> dirtyFields = new ArrayList<String>();
121        for (Property prop : dp.getChildren()) {
122            if (prop.isDirty()) {
123                dirtyFields.add(prop.getName());
124            }
125        }
126        return dirtyFields;
127    }
128
129    @Override
130    public String toString() {
131        return getClass().getSimpleName() + '(' + getSchema() + (dp.isDirty() ? "*" : "") + ')';
132    }
133
134    @Override
135    public void setDirty(String name) throws PropertyNotFoundException {
136        ((AbstractProperty) dp.get(name)).setIsModified();
137    }
138
139    @Override
140    public Object getValue(String path) throws PropertyException {
141        return dp.getValue(path);
142    }
143
144    @Override
145    public Object setValue(String path, Object value) throws PropertyException {
146        Property prop = dp.resolvePath(path);
147        Object oldValue = prop.getValue();
148        prop.setValue(value);
149        return oldValue;
150    }
151
152}