001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.core.api.model.impl;
023
024import java.io.Serializable;
025import java.util.HashMap;
026
027import org.nuxeo.common.utils.Path;
028import org.nuxeo.ecm.core.api.PropertyException;
029import org.nuxeo.ecm.core.api.model.DocumentPart;
030import org.nuxeo.ecm.core.api.model.Property;
031import org.nuxeo.ecm.core.api.model.PropertyVisitor;
032import org.nuxeo.ecm.core.schema.SchemaManager;
033import org.nuxeo.ecm.core.schema.types.Field;
034import org.nuxeo.ecm.core.schema.types.Schema;
035import org.nuxeo.runtime.api.Framework;
036
037/**
038 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
039 */
040public class DocumentPartImpl extends ComplexProperty implements DocumentPart {
041
042    private static final long serialVersionUID = 1L;
043
044    protected Schema schema;
045
046    protected boolean clearComplexPropertyBeforeSet;
047
048    public DocumentPartImpl(Schema schema) {
049        super(null, IS_PHANTOM); // always phantom - will be removed by setValue (createDoc) or init (readDoc)
050        this.schema = schema;
051        // we pre-read this flag only once to avoid looking up and calling the SchemaManager many times
052        clearComplexPropertyBeforeSet = Framework.getService(SchemaManager.class).getClearComplexPropertyBeforeSet();
053    }
054
055    @Override
056    public void internalSetValue(Serializable value) throws PropertyException {
057    }
058
059    // even when DocumentPart is phantom we want want to retrieve its children content
060    @Override
061    public Serializable getValue() throws PropertyException {
062        return internalGetValue();
063    }
064
065    // even when DocumentPart is phantom we want want to retrieve its children content
066    @Override
067    public Serializable getValueForWrite() throws PropertyException {
068        // noinspection CollectionDeclaredAsConcreteClass
069        HashMap<String, Serializable> map = new HashMap<>();
070        for (Property property : getChildren()) {
071            map.put(property.getName(), property.getValueForWrite());
072        }
073        return map;
074    }
075
076    @Override
077    public boolean isContainer() {
078        return true;
079    }
080
081    @Override
082    public Schema getSchema() {
083        return schema;
084    }
085
086    @Override
087    public String getName() {
088        return schema.getName();
089    }
090
091    @Override
092    public Schema getType() {
093        return schema;
094    }
095
096    @Override
097    public Field getField() {
098        throw new UnsupportedOperationException("Document parts are not bound to schema fields");
099    }
100
101    @Override
102    public Path collectPath(Path path) {
103        return path;
104    }
105
106    @Override
107    public Object clone() throws CloneNotSupportedException {
108        return super.clone();
109    }
110
111    @Override
112    public void accept(PropertyVisitor visitor, Object arg) throws PropertyException {
113        visitChildren(visitor, arg);
114    }
115
116    @Override
117    public Property createProperty(Property parent, Field field) {
118        return createProperty(parent, field, 0);
119    }
120
121    @Override
122    public Property createProperty(Property parent, Field field, int flags) {
123        return PropertyFactory.createProperty(parent, field, flags);
124    }
125
126    @Override
127    public boolean getClearComplexPropertyBeforeSet() {
128        return clearComplexPropertyBeforeSet;
129    }
130
131    public boolean isSameAs(DocumentPart dp) {
132        if (dp == null) {
133            return false;
134        }
135        if (dp instanceof ComplexProperty) {
136            return getNonPhantomChildren().equals(((ComplexProperty) dp).getNonPhantomChildren());
137        }
138        return false;
139    }
140
141    @Override
142    public String toString() {
143        return getClass().getSimpleName() + '(' + getName() + (isDirty() ? "*" : "") + ", " + children + ')';
144    }
145
146}