⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classificationimpl.java

📁 Rapla是一个灵活的多用户资源管理系统。它提供的一些功能有:日历GUI
💻 JAVA
字号:
/*--------------------------------------------------------------------------*
 | Copyright (C) 2006 Christopher Kohlhaas                                  |
 |                                                                          |
 | This program is free software; you can redistribute it and/or modify     |
 | it under the terms of the GNU General Public License as published by the |
 | Free Software Foundation. A copy of the license has been included with   |
 | these distribution in the COPYING file, if not go to www.fsf.org         |
 |                                                                          |
 | As a special exception, you are granted the permissions to link this     |
 | program with every library, which license fulfills the Open Source       |
 | Definition as published by the Open Source Initiative (OSI).             |
 *--------------------------------------------------------------------------*/
package org.rapla.entities.dynamictype.internal;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.NoSuchElementException;

import org.rapla.components.util.DateTools;
import org.rapla.entities.Category;
import org.rapla.entities.EntityNotFoundException;
import org.rapla.entities.ReadOnlyException;
import org.rapla.entities.dynamictype.Attribute;
import org.rapla.entities.dynamictype.AttributeType;
import org.rapla.entities.dynamictype.Classification;
import org.rapla.entities.dynamictype.ConstraintIds;
import org.rapla.entities.dynamictype.DynamicType;
import org.rapla.entities.dynamictype.DynamicTypeAnnotations;
import org.rapla.entities.storage.DynamicTypeDependant;
import org.rapla.entities.storage.EntityReferencer;
import org.rapla.entities.storage.EntityResolver;
import org.rapla.entities.storage.RefEntity;
import org.rapla.entities.storage.internal.ReferenceHandler;

/** Use the method <code>newClassification()</code> of class <code>DynamicType</code> to
 *  create a classification. Once created it is not possible to change the
 *  type of a classifiction. But you can replace the classification of an
 *  object implementing <code>Classifiable</code> with a new one.
 *  @see DynamicType
 *  @see org.rapla.entities.dynamictype.Classifiable
 */
public class ClassificationImpl implements Classification,java.io.Serializable, DynamicTypeDependant, EntityReferencer {
    // Don't forget to increase the serialVersionUID when you change the fields
    private static final long serialVersionUID = 1;

    boolean readOnly = false;

    transient String nameString;
    transient boolean isNameUpToDate;
    transient ParsedAnnotation lastParsedAnnotation;

    /** stores the nonreference values like integers,boolean and string.*/
    HashMap attributeValueMap = new HashMap();

    /** stores the references to the dynamictype and the reference values */
    ReferenceHandler referenceHandler = new ReferenceHandler();


    ClassificationImpl(DynamicType dynamicType) {
        referenceHandler.put("parent",dynamicType);
    }

    public void resolveEntities( EntityResolver resolver) throws EntityNotFoundException {
        referenceHandler.resolveEntities( resolver);
    }

    public void setReadOnly(boolean enable) {
        this.readOnly = enable;
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void checkWritable() {
        if ( readOnly )
            throw new ReadOnlyException( this );
    }

    public boolean isRefering(RefEntity obj) {
        return referenceHandler.isRefering(obj);
    }

    public Iterator getReferences() {
        return referenceHandler.getReferences();
    }

    public DynamicType getType() {
        return (DynamicType) referenceHandler.get("parent");
    }

    public String getName(Locale locale) {
        DynamicTypeImpl type = (DynamicTypeImpl)getType();
        ParsedAnnotation parsedAnnotation = type.getParsedAnnotation( DynamicTypeAnnotations.KEY_NAME_FORMAT );
        if ( parsedAnnotation == null) {
            return type.toString();
        }

        if (isNameUpToDate)
        {
            if (parsedAnnotation.equals(lastParsedAnnotation))
                return nameString;
        }
        lastParsedAnnotation =  parsedAnnotation;
        nameString = parsedAnnotation.formatName(type, this, locale);
        isNameUpToDate = true;
        return nameString;
    }

    public String getValueAsString(Attribute attribute,Locale locale)
    {
        Object value = getValue(attribute);
        if (value == null)
            return "";
        if (value instanceof Category) {
            Category rootCategory = (Category) attribute.getConstraint(ConstraintIds.KEY_ROOT_CATEGORY);
            return ((Category) value).getPath(rootCategory, locale);
        }
        if (value instanceof Date) {
            DateFormat format = DateFormat.getDateInstance(DateFormat.MEDIUM,locale);
            format.setTimeZone(DateTools.getTimeZone());
            return format.format((Date) value);
        } else {
            return value.toString();
        }
    }

    public Attribute getAttribute(String key) {
        return getType().getAttribute(key);
    }

    public Attribute[] getAttributes() {
        return getType().getAttributes();
    }

    public boolean needsChange(DynamicType newType) {
    	if ( !hasType (newType )) {
            return false;
    	}
        if ( !newType.getElementKey().equals( getType().getElementKey()))
        	return true;
        Iterator it = referenceHandler.getReferenceKeys();
        while (it.hasNext()) {
        	String referenceKey = (String)it.next();
            RefEntity attribute = ((RefEntity)findAttributeByReferenceKey( getType(), referenceKey));
            if (attribute == null)
            	continue;
            
            if (((DynamicTypeImpl)getType()).hasAttributeChanged( (DynamicTypeImpl)newType , attribute.getId()))
            	return true;
        }
    	it = attributeValueMap.keySet().iterator();
        while (it.hasNext()) {
            Object id = it.next();
            if (((DynamicTypeImpl)getType()).hasAttributeChanged( (DynamicTypeImpl)newType , id))
            	return true;
        }
        return false;
    }

    boolean hasType(DynamicType type) {
        return getType().equals( type);
    }

    public void commitChange(DynamicType type) {
        if ( !hasType (type )) {
            return;
        }
        // update referenced values
        referenceHandler.put("parent", type);
        Iterator it = referenceHandler.getReferenceKeys();
        Collection attributes = new ArrayList();
        Collection removedKeys = new ArrayList();
        Collection removedIds = new ArrayList();
        while (it.hasNext()) {
        	String referenceKey = (String)it.next();
        	if ( referenceKey.equals ("parent") )
        		continue;
        	Attribute attribute = findAttributeByReferenceKey(type, referenceKey ) ;
        	if (attribute != null )
        		attributes.add( attribute);
        	else
        		removedKeys.add( referenceKey );
        }
        it = attributeValueMap.keySet().iterator();
        while (it.hasNext()) {
        	Object id = it.next();
            Attribute attribute = findAttribute(type, id );
            if (attribute != null) {
            	attributes.add ( attribute );
            } else {
            	removedIds.add( id );
            }
        }

        it = attributes.iterator();
        while (it.hasNext()) {
        	Attribute attribute = (Attribute)it.next();
    		Object oldValue = getValue( attribute);
    		Object newValue = attribute.convertValue(oldValue);
    		setValue( attribute,newValue);
        }

        it = removedKeys.iterator();
        while (it.hasNext()) {
        	referenceHandler.removeId ( it.next().toString() );
        }
        it = removedIds.iterator();
        while (it.hasNext()) {
        	attributeValueMap.remove ( it.next().toString() );
        }
        isNameUpToDate = false;
    }

    /** find the attribute of the given type that matches the id */
    private Attribute findAttribute(DynamicType type,Object id) {
        Attribute[] typeAttributes = type.getAttributes();
        for (int i=0; i<typeAttributes.length; i++) {
            if (((RefEntity)typeAttributes[i]).getId().equals(id)) {
                return typeAttributes[i];
            }
        }
        return null;
    }

    /** find the attribute of the given type that matches the id */
    private static Attribute findAttributeByReferenceKey(DynamicType type,String key) {
        Attribute[] typeAttributes = type.getAttributes();
        for (int i=0; i<typeAttributes.length; i++) {
            if (((RefEntity)typeAttributes[i]).getId().toString().equals(key)) {
                return typeAttributes[i];
            }
        }
        return null;
    }


    public void setValue(String key,Object value) {
    	Attribute attribute = getAttribute( key );
    	if ( attribute == null ) {
    		throw new NoSuchElementException("No attribute found for key " + key);
    	}

    	setValue( attribute,value);
    }

    public Object getValue(String key) {
    	Attribute attribute = getAttribute( key );
    	if ( attribute == null ) {
    		throw new NoSuchElementException("No attribute found for key " + key);
    	}

    	return getValue(getAttribute(key));
    }

    public void setValue(Attribute attribute,Object value) {
        checkWritable();
        if (attribute.getType().equals(AttributeType.STRING)
            && value != null
            && ((String)value).length() == 0)
            value = null;

        Object attributeId = ((RefEntity)attribute).getId();
        if (attribute.getType().equals(AttributeType.CATEGORY)) {
            referenceHandler.put(attributeId.toString(), value);
            // we need to remove it from the other the other map
            // Important! The map is for attributes objects not for their string representations
            attributeValueMap.remove(attributeId);
        } else {
        	attributeValueMap.put(attributeId,value);
        	referenceHandler.removeId(attributeId.toString());
        }
        isNameUpToDate = false;
    }

    public Object getValue(Attribute attribute) {
    	if ( attribute == null ) {
    		throw new NullPointerException("Attribute can't be null");
    	}
        Object attributeId = ((RefEntity)attribute).getId();

        // first lookup in attribute map
        Object o = attributeValueMap.get(attributeId);

        // not found, then lookup in the reference map
        if ( o == null)
        	o = referenceHandler.get(attributeId.toString());

        if (o != null)
        	return o;
        else
            return attribute.defaultValue();
    }

    public Object clone() {
        ClassificationImpl clone = new ClassificationImpl(getType());
        clone.referenceHandler = (ReferenceHandler) referenceHandler.clone();
        clone.attributeValueMap = (HashMap) attributeValueMap.clone();
        clone.isNameUpToDate = false;
        clone.readOnly = false;// clones are always writable
        return clone;
    }

     public String toString() {
         if (getType() == null) {
             return super.toString();
         }
         StringBuffer buf = new StringBuffer();
         Attribute[] att = getAttributes();
         for ( int i=0;i<att.length; i++){
             if ( i> 0)
                 buf.append(", ");
             buf.append( att[i].getKey());
             buf.append("=");
             buf.append( getValue( att[i]));
         }
         return buf.toString();
     }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -