001/*
002 * (C) Copyright 2006-2007 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 *     Dragos Mihalache
018 */
019package org.nuxeo.ecm.core.uidgen;
020
021import org.apache.commons.logging.Log;
022import org.apache.commons.logging.LogFactory;
023import org.nuxeo.ecm.core.api.DocumentModel;
024import org.nuxeo.ecm.core.api.NuxeoException;
025import org.nuxeo.ecm.core.api.PropertyException;
026import org.nuxeo.ecm.core.api.model.PropertyNotFoundException;
027import org.nuxeo.ecm.core.schema.SchemaManager;
028import org.nuxeo.ecm.core.schema.types.Schema;
029import org.nuxeo.runtime.api.Framework;
030
031/**
032 * The abstract class adds some useful methods.
033 */
034public abstract class AbstractUIDGenerator implements UIDGenerator {
035
036    private static final Log log = LogFactory.getLog(AbstractUIDGenerator.class);
037
038    private UIDSequencer sequencer;
039
040    private String[] propertyNames;
041
042    @Override
043    public final void setSequencer(UIDSequencer sequencer) {
044        if (null == sequencer) {
045            throw new IllegalArgumentException("null sequencer");
046        }
047        this.sequencer = sequencer;
048    }
049
050    protected int getNext(final DocumentModel document) {
051        if (null == sequencer) {
052            throw new IllegalStateException("sequencer not defined");
053        }
054        final String key = getSequenceKey(document);
055        assert key != null;
056        return sequencer.getNext(key);
057    }
058
059    @Override
060    public String getPropertyName() {
061        if (propertyNames.length == 0) {
062            log.warn("No propertyName specified");
063            return null;
064        }
065        return propertyNames[0];
066    }
067
068    @Override
069    public void setPropertyName(String propertyName) {
070        propertyNames = new String[] { propertyName };
071    }
072
073    @Override
074    public void setPropertyNames(String[] propertyNames) {
075        this.propertyNames = propertyNames;
076    }
077
078    @Override
079    public String[] getPropertyNames() {
080        return propertyNames;
081    }
082
083    /**
084     * Checks if the property with the given name is defined and is not null.
085     */
086    protected final boolean isPropValueDefined(String propName, DocumentModel document) {
087        try {
088            Object val = document.getProperty(getSchemaName(propName), getFieldName(propName));
089            return val != null;
090        } catch (PropertyException e) {
091            return false;
092        }
093    }
094
095    protected final String str(String propName, DocumentModel document) {
096        Object val = document.getProperty(getSchemaName(propName), getFieldName(propName));
097        if (val == null) {
098            return null;
099        }
100        if (val instanceof String) {
101            return (String) val;
102        }
103        throw new NuxeoException("Doc property '" + propName + "' is not of String type.");
104    }
105
106    @Override
107    public void setUID(DocumentModel document) throws PropertyNotFoundException {
108        String uid = createUID(document);
109        for (String propertyName : propertyNames) {
110            try {
111                document.setProperty(getSchemaName(propertyName), getFieldName(propertyName), uid);
112            } catch (PropertyNotFoundException e) {
113                e.addInfo(String.format("Cannot set uid %s on property %s for doc %s", uid, propertyName, document));
114                throw e;
115            }
116        }
117    }
118
119    // helper method to deprecate
120    private static String getSchemaName(String propertyName) {
121        String[] s = propertyName.split(":");
122        String prefix = s[0];
123        SchemaManager tm = Framework.getService(SchemaManager.class);
124        Schema schema = tm.getSchemaFromPrefix(prefix);
125        if (schema == null) {
126            // fall back on prefix as it may be the schema name
127            return prefix;
128        } else {
129            return schema.getName();
130        }
131    }
132
133    // helper method to deprecate
134    private static String getFieldName(String propertyName) {
135        String[] s = propertyName.split(":");
136        return s[1];
137    }
138
139}