/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/common/PropertyName.java,v 1.6 2004/12/21 16:12:44 luetzkendorf Exp $
 * $Revision: 1.6 $
 * $Date: 2004/12/21 16:12:44 $
 *
 * ====================================================================
 *
 * Copyright 1999 The Apache Software Foundation 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.apache.slide.common;

import java.util.HashMap;
import java.util.Map;

import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;

/**
 * This class is a container for the name and namespace of a property.
 *
 * @version $Revision: 1.6 $
 *
 **/
public class PropertyName {
    
    private static Map instances = new HashMap();
    
    public static final PropertyName CONTENT_LANGUAGE = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.CONTENT_LANGUAGE);
    public static final PropertyName CONTENT_LENGTH = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.CONTENT_LENGTH);
    public static final PropertyName CONTENT_TYPE = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.CONTENT_TYPE);
    public static final PropertyName CREATION_DATE = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.CREATION_DATE);
    public static final PropertyName CREATION_USER = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.CREATION_USER);
    public static final PropertyName DISPLAY_NAME = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.NAME);
    public static final PropertyName ETAG = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.ETAG);
    public static final PropertyName LAST_MODIFIED = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.LAST_MODIFIED);
    public static final PropertyName MODIFICATION_DATE = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.MODIFICATION_DATE);
    public static final PropertyName MODIFICATION_USER = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.MODIFICATION_USER);
    public static final PropertyName OWNER = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.OWNER);
    public static final PropertyName RESOURCE_TYPE = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.RESOURCE_TYPE);
    public static final PropertyName SOURCE = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.SOURCE);
    public static final PropertyName REDIRECT_LIFETIME = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.REDIRECT_LIFETIME);
    public static final PropertyName REFTARGET = 
        PropertyName.getPropertyName(NodeRevisionDescriptor.REFTARGET);

    
    /**
     * The name of the Property.
     */
    protected String name = null;
    
    /**
     * The namespace of the Property.
     */
    protected String namespace = null;
    
    private int hashCode;
    
    /**
     * Creates a PropertyName within the {@link NodeProperty#DEFAULT_NAMESPACE
     * default namespace}.
     *
     * @deprecated use {@link #getPropertyName(String, String)}
     * @param      name       the name of the Property.
     */
    public PropertyName(String name) {
        this(name, NodeProperty.DEFAULT_NAMESPACE);
    }
    
    /**
     * Creates a PropertyName.
     *
     * @deprecated use {@link #getPropertyName(String, String)}
     * @param      name       the name of the Property.
     * @param      namespace  the namespace of the Property.
     */
    public PropertyName(String name, String namespace) {
        this.name = name.intern();
        this.namespace = namespace.intern();

        hashCode = this.name.hashCode();
        hashCode += 13 * this.namespace.hashCode();
    }
    
    /**
     * Factory method.
     * @param name the properties name 
     * @param namespace the properties namespace
     * @return a property name object 
     */
    public static PropertyName getPropertyName(String name, String namespace) {
        Map namespaceMap = (Map)instances.get(namespace);
        if (namespaceMap == null) {
            namespaceMap = new HashMap();
            instances.put(namespace.intern(), namespaceMap);
        }
        
        PropertyName result = (PropertyName)namespaceMap.get(name);
        if (result == null) {
            result = new PropertyName(name, namespace);
            namespaceMap.put(result.getName(), result);
        }
        
        return result;
    }
    
    /**
     * Factory method. Creates a property name with the default <code>DAV:</code> namespace.
     * @param name the properties name 
     * @return a property name object 
     */   
    public static PropertyName getPropertyName(String name) {
        return getPropertyName(name, NodeProperty.DEFAULT_NAMESPACE);
    }
    
    /**
     * Returns the name of the property.
     *
     * @return     the name of the property.
     */
    public String getName() {
        return name;
    }
    
    /**
     * Returns the namespace of the property.
     *
     * @return     the namespace of the property.
     */
    public String getNamespace() {
        return namespace;
    }
    
    /**
     * Returns <code>true</code> if <code>other</code> is a PropertyName
     * and the name and namespace are equal to this intance' name and namespace.
     *
     * @param      other  the Object to test for equality.
     *
     * @return     <code>true</code> if the object is equal to this one.
     */
    public boolean equals(Object other) {
        
        if (this == other) {
            return true;
        }
        
       if (other instanceof PropertyName) {
           PropertyName that = (PropertyName)other;
           
           return this.name == that.name && this.namespace == that.namespace;
       }
       
       return false;
    }
    
    /**
     * Returns the hash code of this instance. Due to definition equal objects
     * must have the same hash code.
     *
     * @return     the hash code of this instance.
     */
    public int hashCode() {
        return hashCode;
    }
    
    /**
     * Returns a String representation of the PropertyName.
     *
     * @return     a String representation of the PropertyName.
     */
    public String toString() {
        return new StringBuffer()
            .append(this.namespace)
            .append(':')
            .append(this.name)
            .toString();
    }
}

