org.zkoss.zk.ui.metainfo.ComponentDefinitionMap Maven / Gradle / Ivy
/* ComponentDefinitionMap.java
Purpose:
Description:
History:
Mon Sep 4 20:20:36 2006, Created by tomyeh
Copyright (C) 2006 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
This program is distributed under LGPL Version 2.1 in the hope that
it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.zk.ui.metainfo;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A map of component definitions.
* Used with {@link PageDefinition#getComponentDefinitionMap}
* and {@link LanguageDefinition}.
*
* It is thread-safe (since it is used in {@link LanguageDefinition}).
*
* @author tomyeh
*/
public class ComponentDefinitionMap implements Cloneable, java.io.Serializable {
/** A map of component definition defined in this page. */
private transient Map _compdefs;
/** Map(String clsnm, ComponentDefinition compdef). */
private transient Map _compdefsByClass;
/** Whether the element name is case-insensitive. */
private final boolean _ignoreCase;
/** Constructor.
*/
public ComponentDefinitionMap(boolean ignoreCase) {
_ignoreCase = ignoreCase;
}
/** Returns whether the component names are case-insensitive.
*/
public boolean isCaseInsensitive() {
return _ignoreCase;
}
/** Returns a readonly collection of the names (String)
* of component definitions defined in this map.
*/
public Collection getNames() {
if (_compdefs != null)
return _compdefs.keySet();
return Collections.emptyList();
}
/** Returns a readonly collection of component definitions
* ({@link ComponentDefinition}) defined in this map.
* @since 3.6.3
*/
public Collection getDefinitions() {
if (_compdefs != null)
return _compdefs.values();
return Collections.emptyList();
}
/** Adds a component definition to this map.
*
* Thread safe.
*/
public void add(ComponentDefinition compdef) {
if (compdef == null)
throw new IllegalArgumentException("null");
String name = compdef.getName();
if (isCaseInsensitive())
name = name.toLowerCase(java.util.Locale.ENGLISH);
Object implcls = compdef.getImplementationClass();
if (implcls instanceof Class)
implcls = ((Class) implcls).getName();
synchronized (this) {
if (_compdefs == null) {
_compdefsByClass = Collections.synchronizedMap(new HashMap(4));
_compdefs = Collections.synchronizedMap(new HashMap(4));
}
_compdefs.put(name, compdef);
_compdefsByClass.put((String) implcls, compdef);
}
}
/** Returns whether the specified component exists.
*/
public boolean contains(String name) {
return _compdefs != null
&& _compdefs.containsKey(isCaseInsensitive() ? name.toLowerCase(java.util.Locale.ENGLISH) : name);
}
/** Returns the component definition of the specified name, or null if not
* not found.
*
* Note: unlike {@link LanguageDefinition#getComponentDefinition},
* this method doesn't throw ComponentNotFoundException if not found.
* It just returns null.
*/
public ComponentDefinition get(String name) {
return _compdefs != null
? _compdefs.get(isCaseInsensitive() ? name.toLowerCase(java.util.Locale.ENGLISH) : name) : null;
}
/** Returns the component definition of the specified class, or null if not
* found.
*
*
Note: unlike {@link LanguageDefinition#getComponentDefinition},
* this method doesn't throw ComponentNotFoundException if not found.
* It just returns null.
*/
public ComponentDefinition get(Class cls) {
if (_compdefsByClass != null) {
for (; cls != null; cls = cls.getSuperclass()) {
final ComponentDefinition compdef = _compdefsByClass.get(cls.getName());
if (compdef != null)
return compdef;
}
}
return null;
}
//Serializable//
//NOTE: they must be declared as private
private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
s.defaultWriteObject();
if (_compdefs != null) {
synchronized (_compdefs) {
s.writeInt(_compdefs.size());
for (ComponentDefinition compdef : _compdefs.values())
s.writeObject(compdef);
}
} else {
s.writeInt(0);
}
}
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
int cnt = s.readInt();
while (--cnt >= 0)
add((ComponentDefinition) s.readObject());
}
//Cloneable//
public Object clone() {
final ComponentDefinitionMap clone;
try {
clone = (ComponentDefinitionMap) super.clone();
clone._compdefs = Collections.synchronizedMap(new HashMap(_compdefs));
clone._compdefsByClass = Collections
.synchronizedMap(new HashMap(_compdefsByClass));
} catch (CloneNotSupportedException ex) {
throw new InternalError();
}
return clone;
}
}