001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Dragos Mihalache
016 */
017package org.nuxeo.ecm.core.uidgen;
018
019import org.apache.commons.logging.Log;
020import org.apache.commons.logging.LogFactory;
021import org.nuxeo.ecm.core.api.DocumentModel;
022import org.nuxeo.ecm.core.api.NuxeoException;
023import org.nuxeo.ecm.core.api.PropertyException;
024import org.nuxeo.ecm.core.api.model.PropertyNotFoundException;
025import org.nuxeo.ecm.core.schema.SchemaManager;
026import org.nuxeo.ecm.core.schema.types.Schema;
027import org.nuxeo.runtime.api.Framework;
028
029/**
030 * The abstract class adds some useful methods.
031 */
032public abstract class AbstractUIDGenerator implements UIDGenerator {
033
034    private static final Log log = LogFactory.getLog(AbstractUIDGenerator.class);
035
036    private UIDSequencer sequencer;
037
038    private String[] propertyNames;
039
040    @Override
041    public final void setSequencer(UIDSequencer sequencer) {
042        if (null == sequencer) {
043            throw new IllegalArgumentException("null sequencer");
044        }
045        this.sequencer = sequencer;
046    }
047
048    protected int getNext(final DocumentModel document) {
049        if (null == sequencer) {
050            throw new IllegalStateException("sequencer not defined");
051        }
052        final String key = getSequenceKey(document);
053        assert key != null;
054        return sequencer.getNext(key);
055    }
056
057    @Override
058    public String getPropertyName() {
059        if (propertyNames.length == 0) {
060            log.warn("No propertyName specified");
061            return null;
062        }
063        return propertyNames[0];
064    }
065
066    @Override
067    public void setPropertyName(String propertyName) {
068        propertyNames = new String[] { propertyName };
069    }
070
071    @Override
072    public void setPropertyNames(String[] propertyNames) {
073        this.propertyNames = propertyNames;
074    }
075
076    @Override
077    public String[] getPropertyNames() {
078        return propertyNames;
079    }
080
081    /**
082     * Checks if the property with the given name is defined and is not null.
083     */
084    protected final boolean isPropValueDefined(String propName, DocumentModel document) {
085        try {
086            Object val = document.getProperty(getSchemaName(propName), getFieldName(propName));
087            return val != null;
088        } catch (PropertyException e) {
089            return false;
090        }
091    }
092
093    protected final String str(String propName, DocumentModel document) {
094        Object val = document.getProperty(getSchemaName(propName), getFieldName(propName));
095        if (val == null) {
096            return null;
097        }
098        if (val instanceof String) {
099            return (String) val;
100        }
101        throw new NuxeoException("Doc property '" + propName + "' is not of String type.");
102    }
103
104    @Override
105    public void setUID(DocumentModel document) throws PropertyNotFoundException {
106        String uid = createUID(document);
107        for (String propertyName : propertyNames) {
108            try {
109                document.setProperty(getSchemaName(propertyName), getFieldName(propertyName), uid);
110            } catch (PropertyNotFoundException e) {
111                e.addInfo(String.format("Cannot set uid %s on property %s for doc %s", uid, propertyName, document));
112                throw e;
113            }
114        }
115    }
116
117    // helper method to deprecate
118    private static String getSchemaName(String propertyName) {
119        String[] s = propertyName.split(":");
120        String prefix = s[0];
121        SchemaManager tm = Framework.getService(SchemaManager.class);
122        Schema schema = tm.getSchemaFromPrefix(prefix);
123        if (schema == null) {
124            // fall back on prefix as it may be the schema name
125            return prefix;
126        } else {
127            return schema.getName();
128        }
129    }
130
131    // helper method to deprecate
132    private static String getFieldName(String propertyName) {
133        String[] s = propertyName.split(":");
134        return s[1];
135    }
136
137}