001/*
002 * Copyright (c) 2006-2014 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 *     Florent Guillaume
011 */
012package org.nuxeo.ecm.core.storage.sql.coremodel;
013
014import java.io.Serializable;
015import java.util.Collections;
016import java.util.List;
017
018import org.nuxeo.ecm.core.api.DocumentNotFoundException;
019import org.nuxeo.ecm.core.model.Document;
020import org.nuxeo.ecm.core.schema.types.ComplexType;
021import org.nuxeo.ecm.core.storage.sql.Model;
022import org.nuxeo.ecm.core.storage.sql.Node;
023
024public class SQLDocumentVersion extends SQLDocumentLive {
025
026    private final Node versionableNode;
027
028    public static class VersionNotModifiableException extends RuntimeException {
029        private static final long serialVersionUID = 1L;
030
031        public VersionNotModifiableException() {
032            super();
033        }
034
035        public VersionNotModifiableException(String message) {
036            super(message);
037        }
038
039    }
040
041    protected SQLDocumentVersion(Node node, ComplexType type, SQLSession session, boolean readonly) {
042        super(node, type, session, readonly);
043        Serializable versionSeriesId = getPropertyValue(Model.VERSION_VERSIONABLE_PROP);
044        if (versionSeriesId == null) {
045            throw new DocumentNotFoundException("Version was removed: " + node.getId());
046        }
047        versionableNode = session.getNodeById(versionSeriesId);
048    }
049
050    /*
051     * ----- version-specific overrides -----
052     */
053
054    @Override
055    public boolean isVersion() {
056        return true;
057    }
058
059    @Override
060    public boolean isCheckedOut() {
061        return false;
062    }
063
064    @Override
065    public boolean isVersionSeriesCheckedOut() {
066        if (versionableNode == null) {
067            return false;
068        }
069        return !Boolean.TRUE.equals(versionableNode.getSimpleProperty(Model.MAIN_CHECKED_IN_PROP).getValue());
070    }
071
072    @Override
073    public boolean isMajorVersion() {
074        return Long.valueOf(0).equals(getPropertyValue(Model.MAIN_MINOR_VERSION_PROP));
075    }
076
077    @Override
078    public boolean isLatestVersion() {
079        return Boolean.TRUE.equals(getPropertyValue(Model.VERSION_IS_LATEST_PROP));
080    }
081
082    @Override
083    public boolean isLatestMajorVersion() {
084        return Boolean.TRUE.equals(getPropertyValue(Model.VERSION_IS_LATEST_MAJOR_PROP));
085    }
086
087    @Override
088    public Document getWorkingCopy() {
089        if (versionableNode == null) {
090            return null;
091        }
092        return session.getDocumentByUUID(versionableNode.getId().toString());
093    }
094
095    @Override
096    public Document getBaseVersion() {
097        return null;
098    }
099
100    @Override
101    public String getVersionSeriesId() {
102        Serializable versionSeriesId = getPropertyValue(Model.VERSION_VERSIONABLE_PROP);
103        return session.idToString(versionSeriesId);
104    }
105
106    @Override
107    public Document getSourceDocument() {
108        return getWorkingCopy();
109    }
110
111    @Override
112    public String getPath() {
113        if (versionableNode == null) {
114            return null; // TODO return what? error?
115        }
116        return session.getPath(versionableNode);
117    }
118
119    @Override
120    public Document getParent() {
121        if (versionableNode == null) {
122            return null;
123        }
124        return session.getParent(versionableNode);
125    }
126
127    // protected Property getACLProperty() not overriden, no ACL anyway
128
129    /*
130     * ----- folder overrides -----
131     */
132
133    @Override
134    public boolean isFolder() {
135        return false;
136    }
137
138    @Override
139    public void orderBefore(String src, String dest) {
140        throw new VersionNotModifiableException();
141    }
142
143    @Override
144    public Document addChild(String name, String typeName) {
145        throw new VersionNotModifiableException();
146    }
147
148    @Override
149    public Document getChild(String name) {
150        throw new DocumentNotFoundException(name);
151    }
152
153    @Override
154    public List<Document> getChildren() {
155        return Collections.emptyList();
156    }
157
158    @Override
159    public List<String> getChildrenIds() {
160        return Collections.emptyList();
161    }
162
163    @Override
164    public boolean hasChild(String name) {
165        return false;
166    }
167
168    @Override
169    public boolean hasChildren() {
170        return false;
171    }
172
173    /*
174     * ----- versioning overrides -----
175     */
176
177    @Override
178    public Document checkIn(String label, String description) {
179        throw new VersionNotModifiableException();
180    }
181
182    @Override
183    public void checkOut() {
184        throw new VersionNotModifiableException();
185    }
186
187    @Override
188    public void restore(Document version) {
189        throw new VersionNotModifiableException();
190    }
191
192    @Override
193    public Document getVersion(String label) {
194        return null;
195    }
196
197    /*
198     * ----- property write overrides -----
199     */
200
201    @Override
202    public void setPropertyValue(String name, Serializable value) {
203        if (isReadOnlyProperty(name)) {
204            throw new VersionNotModifiableException(String.format("Cannot set property on a version: %s = %s", name,
205                    value));
206        }
207        // import
208        super.setPropertyValue(name, value);
209    }
210
211    protected boolean isReadOnlyProperty(String name) {
212        return isReadOnly() && !isVersionWritableProperty(name);
213    }
214
215    /*
216     * ----- equals/hashcode -----
217     */
218
219    @Override
220    public boolean equals(Object other) {
221        if (other == this) {
222            return true;
223        }
224        if (other == null) {
225            return false;
226        }
227        if (other.getClass() == this.getClass()) {
228            return equals((SQLDocumentVersion) other);
229        }
230        return false;
231    }
232
233    private boolean equals(SQLDocumentVersion other) {
234        return getNode().equals(other.getNode());
235    }
236
237    @Override
238    public int hashCode() {
239        return getNode().hashCode();
240    }
241
242}