All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.wikitty.entities.WikittyCopyOnWrite Maven / Gradle / Ivy

The newest version!
/*
 * #%L
 * Wikitty :: api
 * %%
 * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */
package org.nuiton.wikitty.entities;

import java.beans.PropertyChangeListener;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.wikitty.WikittyException;

/** this class wrap a wikitty in a proxy that copy the wikitty before applying any change
 *
 * It is used for caching purpose. This class own a reference to an actual
 * wikitty, multiple instance of this class can own some references to a same
 * actual wikitty. To prevent the target to be modified, a copy is created
 * to prevent side-effect.
 * 
 * So, when a wikitty restored from cache is modified, a copy is modified, so
 * if change are cancelled, next restore will restore the original and not
 * the modified version (until the modified version is stored).
 * 
 * used in {@link WikittyServiceCached}
 */
public class WikittyCopyOnWrite implements Wikitty {

    private static final long serialVersionUID = 1L;

    private static final Log log = LogFactory.getLog(WikittyCopyOnWrite.class);

    protected Wikitty target;

    protected boolean targetIsACopy = false;

    /** only WikittyService with cache should create instances */
    public WikittyCopyOnWrite(Wikitty target) {
        this.target = target;
    }

    @Override
    public String getPreloadPattern() {
        return target.getPreloadPattern();
    }

    @Override
    public void setPreloadPattern(String preloadPattern) {
        if (!ObjectUtils.equals(preloadPattern, getPreloadPattern())) {
            substituteTargetWithCopy();
            target.setPreloadPattern(preloadPattern);
        }
    }

    @Override
    public Set getAllPreloadPattern() {
        return target.getAllPreloadPattern();
    }

    @Override
    public Map getPreloaded() {
        return target.getPreloaded();
    }

    @Override
    public void setPreloaded(Map preloaded) {
        substituteTargetWithCopy();
        target.setPreloaded(preloaded);
    }

    @Override
    public void addPreloaded(Wikitty w) {
        if (w != null) {
            if (!getPreloaded().containsKey(w.getWikittyId())) {
                substituteTargetWithCopy();
                target.addPreloaded(w);
            }
        }
    }

    @Override
    public void replaceWith(Wikitty w) {
        replaceWith(w, false);
    }

    @Override
    public void replaceWith(Wikitty w, boolean force) {
        if (this == w) {
            return;
        }
        substituteTargetWithCopy();
        target.replaceWith(w, force);
    }

    public Wikitty getTarget() {
        return target;
    }

    /** replaceWith {@link #target} with a clone
     *
     * this method must be called to prevent any modification on target
     */
    protected void substituteTargetWithCopy() {
        // test make a the copy once
        if (! targetIsACopy) {
            try {
                target = target.clone();
                targetIsACopy = true;
                if (log.isTraceEnabled()) {
                    log.trace(this + " now has for target " + target);
                }
            } catch (CloneNotSupportedException eee) {
                throw new WikittyException(String.format(
                        "unable to clone wikitty %s", target), eee);
            }
        }
    }

    /**
     * ATTENTION, la condition d'egalite n'est pas faite sur le type d'objet,
     * mais seulement sur le contenu des donnees. Le equals repond a la question
     * "Est-ce qu'on represente le meme wikitty ?".
     *
     * @param obj
     * @return
     */
    @Override
    public boolean equals(Object obj) {
        return target.equals(obj);
    }

    @Override
    public String toString(String extName) {
        return target.toString(extName);
    }

    public String toStringAllField() {
        return target.toStringAllField();
    }

    @Override
    public int hashCode() {
        return target.hashCode();
    }

    @Override
    public String toString() {
        return target.toString();
    }

    @Override
    public Wikitty clone() throws CloneNotSupportedException {
        // return a clone of the target
        return target.clone();
    }

    /* ** below are only delegation code with copy-on-write */

    @Override
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        substituteTargetWithCopy();
        target.addPropertyChangeListener(listener);
    }

    @Override
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        substituteTargetWithCopy();
        target.removePropertyChangeListener(listener);
    }

    @Override
    public void addPropertyChangeListener(String propertyName,
            PropertyChangeListener listener) {
        substituteTargetWithCopy();
        target.addPropertyChangeListener(propertyName, listener);
    }

    @Override
    public void removePropertyChangeListener(String propertyName,
            PropertyChangeListener listener) {
        substituteTargetWithCopy();
        target.removePropertyChangeListener(propertyName, listener);
    }

    @Override
    public String getId() {
        return target.getWikittyId();
    }

    public String getWikittyId() {
        return target.getWikittyId();
    }

    @Override
    public boolean isDeleted() {
        return target.isDeleted();
    }

    @Override
    public Date getDeleteDate() {
        return target.getDeleteDate();
    }

    @Override
    public void setDeleteDate(Date delete) {
        if (!ObjectUtils.equals(delete, getDeleteDate())) {
            substituteTargetWithCopy();
            target.setDeleteDate(delete);
        }
    }

    @Override
    public void addExtension(WikittyExtension ext) {
        if (!target.getExtensions().contains(ext)) {
            substituteTargetWithCopy();
            target.addExtension(ext);
        }
    }

    @Override
    public void addExtension(Collection exts) {
        if (!target.getExtensions().containsAll(exts)) {
            substituteTargetWithCopy();
            target.addExtension(exts);
        }
    }

    @Override
    public void removeExtension(String ext) {
        if (target.getExtensionNames().contains(ext)) {
            substituteTargetWithCopy();
            target.removeExtension(ext);
        }
    }

    @Override
    public void removeExtensions(Collection ext) {
        if (CollectionUtils.containsAny(target.getExtensionNames(), ext)) {
            substituteTargetWithCopy();
            target.removeExtensions(ext);
        }
    }

    @Override
    public boolean hasExtension(String extName) {
        return target.hasExtension(extName);
    }

    @Override
    public boolean hasField(String extName, String fieldName) {
        return target.hasField(extName, fieldName);
    }

    @Override
    public boolean hasField(String fqfieldName) {
        return target.hasField(fqfieldName);
    }

    @Override
    public WikittyExtension getExtension(String ext) {
        return target.getExtension(ext);
    }

    @Override
    public Collection getExtensionNames() {
        return target.getExtensionNames();
    }

    @Override
    public Collection getExtensionFields(String ext) {
        Collection result = target.getExtension(ext).getFieldNames();
        return result;
    }

    @Override
    public Collection getExtensions() {
        return target.getExtensions();
    }

    @Override
    public Collection getExtensionDependencies(String ext,
            boolean recursively) {
        return target.getExtensionDependencies(ext, recursively);
    }

    @Override
    public FieldType getFieldType(String fqfieldName) {
        return target.getFieldType(fqfieldName);
    }

    @Override
    public FieldType getFieldType(String extName, String fieldName) {
        return target.getFieldType(extName, fieldName);
    }

    @Override
    public void setField(String ext, String fieldName, Object value) {
        substituteTargetWithCopy();
        target.setField(ext, fieldName, value);
    }

    @Override
    public Object getFieldAsObject(String ext, String fieldName) {
        return target.getFieldAsObject(ext, fieldName);
    }

    @Override
    public byte[] getFieldAsBytes(String ext, String fieldName) {
        return target.getFieldAsBytes(ext, fieldName);
    }

    @Override
    public boolean getFieldAsBoolean(String ext, String fieldName) {
        return target.getFieldAsBoolean(ext, fieldName);
    }

    @Override
    public BigDecimal getFieldAsBigDecimal(String ext, String fieldName) {
        return target.getFieldAsBigDecimal(ext, fieldName);
    }

    @Override
    public int getFieldAsInt(String ext, String fieldName) {
        return target.getFieldAsInt(ext, fieldName);
    }

    @Override
    public long getFieldAsLong(String ext, String fieldName) {
        return target.getFieldAsLong(ext, fieldName);
    }

    @Override
    public float getFieldAsFloat(String ext, String fieldName) {
        return target.getFieldAsFloat(ext, fieldName);
    }

    @Override
    public double getFieldAsDouble(String ext, String fieldName) {
        return target.getFieldAsDouble(ext, fieldName);
    }

    @Override
    public String getFieldAsString(String ext, String fieldName) {
        return target.getFieldAsString(ext, fieldName);
    }

    @Override
    public Date getFieldAsDate(String ext, String fieldName) {
        return target.getFieldAsDate(ext, fieldName);
    }

    @Override
    public String getFieldAsWikitty(String ext, String fieldName) {
        return target.getFieldAsWikitty(ext, fieldName);
    }

    @Override
    public Wikitty getFieldAsWikitty(String extName, String fieldName, boolean exceptionIfNotLoaded) {
        return target.getFieldAsWikitty(extName, fieldName, exceptionIfNotLoaded);
    }

    @Override
    public  List getFieldAsList(String ext, String fieldName,
            Class clazz) {
        return target.getFieldAsList(ext, fieldName, clazz);
    }

    @Override
    public List getFieldAsWikittyList(String ext, String fieldName,
    boolean exceptionIfNotLoaded) {
        return target.getFieldAsWikittyList(ext, fieldName, exceptionIfNotLoaded);
    }

    @Override
    public  Set getFieldAsSet(String ext, String fieldName, Class clazz) {
        return target.getFieldAsSet(ext, fieldName, clazz);
    }

    @Override
    public Set getFieldAsWikittySet(String ext, String fieldName,
    boolean exceptionIfNotLoaded) {
        return target.getFieldAsWikittySet(ext, fieldName, exceptionIfNotLoaded);
    }

    @Override
    public void addToField(String ext, String fieldName, Object value) {
        substituteTargetWithCopy();
        target.addToField(ext, fieldName, value);
    }

    @Override
    public void removeFromField(String ext, String fieldName, Object value) {
        substituteTargetWithCopy();
        target.removeFromField(ext, fieldName, value);
    }

    @Override
    public void clearField(String ext, String fieldName) {
        substituteTargetWithCopy();
        target.clearField(ext, fieldName);
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#addToField(String, Object)
     */
    @Override
    public void addToField(String fqFieldName, Object value) {
        substituteTargetWithCopy();
        target.addToField(fqFieldName, value);
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#removeFromField(String, Object)
     */
    @Override
    public void removeFromField(String fqFieldName, Object value) {
        substituteTargetWithCopy();
        target.removeFromField(fqFieldName, value);
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#clearField(String)
     */
    @Override
    public void clearField(String fqFieldName) {
        substituteTargetWithCopy();
        target.clearField(fqFieldName);
    }

    @Override
    public Set fieldNames() {
        return target.fieldNames();
    }

    @Override
    public Map getFieldValue() {
        return target.getFieldValue();
    }

    @Override
    public Set getAllFieldNames() {
        return target.getAllFieldNames();
    }

    @Override
    public Object getFqField(String fqFieldName) {
        return target.getFqField(fqFieldName);
    }

    @Override
    public String getVersion() {
        return target.getWikittyVersion();
    }

    @Override
    public void setVersion(String version) {
        substituteTargetWithCopy();
        target.setWikittyVersion(version);
    }

    @Override
    public String getWikittyVersion() {
        return target.getWikittyVersion();
    }

    @Override
    public void setWikittyVersion(String version) {
        substituteTargetWithCopy();
        target.setWikittyVersion(version);
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#getDirty()
     */
    @Override
    public Set getDirty() {
        return target.getDirty();
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#clearDirty()
     */
    @Override
    public void clearDirty() {
        substituteTargetWithCopy();
        target.clearDirty();
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#setFqField(String, Object)
     */
    @Override
    public void setFqField(String fieldName, Object value) {
        substituteTargetWithCopy();
        target.setFqField(fieldName, value);
    }

    @Override
    public boolean isEmpty() {
        return target.isEmpty();
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#hasMetaExtension(String, String)
     */
    @Override
    public boolean hasMetaExtension(String metaExtensionName,
                                    String extensionName) {
        return target.hasMetaExtension(metaExtensionName, extensionName);
    }
    
    /**
     * @see org.nuiton.wikitty.Wikitty#addMetaExtension(WikittyExtension, WikittyExtension)
     */
    @Override
    public void addMetaExtension(WikittyExtension metaExtension,
            WikittyExtension extension) {
        substituteTargetWithCopy();
        target.addMetaExtension(metaExtension, extension);
    }

    /**
     * @see org.nuiton.wikitty.Wikitty#addMetaExtension(WikittyExtension, String)
     */
    @Override
    public void addMetaExtension(WikittyExtension metaExtension,
            String extensionFqn) {
        substituteTargetWithCopy();
        target.addMetaExtension(metaExtension, extensionFqn);
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy