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

org.zkoss.zk.ui.metainfo.ComponentDefinition Maven / Gradle / Ivy

There is a newer version: 10.0.0-jakarta
Show newest version
/* ComponentDefinition.java

	Purpose:
		
	Description:
		
	History:
		Tue May 31 17:54:45     2005, Created by tomyeh

Copyright (C) 2005 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.net.URL;
import java.util.Collection;
import java.util.Map;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.util.Composer;
import org.zkoss.zk.xel.ExValue;

/**
 * A component definition.
 * Like class in Java, a {@link ComponentDefinition} defines the behavior
 * of a component.
 *
 * 

The implementation need NOT to be thread safe, since the caller * has to {@link #clone} first if accessed concurrently. * * @author tomyeh */ public interface ComponentDefinition extends Cloneable { /** Returns the language definition, or null if it is a temporary definition * belonging to a page. */ public LanguageDefinition getLanguageDefinition(); /** Returns name of this component definition (never null). * It is unique in the same language, {@link LanguageDefinition}, * if it belongs to a language, i.e., * {@link #getLanguageDefinition} is not null. */ public String getName(); /** Returns the property name to which the text enclosed within * the element (associated with this component definition) is assigned to. * *

Default: null (means to create a Label component as the child) * *

For example, if {@link #getTextAs} returns null, then * a Label component is created as a child of comp * with the "Hi Text" value in the following example: * *

<comp>
	 *  Hi Text
	 *</comp>
* *

In other words, it is equivalent to * *

<comp>
	 *  <label value="Hi Text"/>
	 *</comp>
* *

On the other hand, if {@link #getTextAs} returns a non-empty string, * say, "content", then * "Hi Text" is assigned to the content property of comp. * In other words, it is equivalent to * *

<comp content="Hi Text"/>
	 *</comp>
* *

It is also the same as * *

<comp>
	 *  <attribute name="content"/>
	 *  Hi Text
	 *  </attribute>
	 *</comp>
* *

To enable it, you can declare text-as in * the component definition in lang.xml or lang-addon.xml: * *

<component>
	 *  <component-name>html</component-name>
	 *  <text-as>content</text-as>
	 *...
* *

Notice that it is valid to have XML fragment, including XML elements, * within the element. For example,

<html>
	<ul>
	<li forEach="apple, orange">${each}</li>
	</ul>
	</html>
* *

If the component allows child components, it is better not to try * XML fragment as the plain text. And then, it shall return true * in {@link #isChildAllowedInTextAs}. Example, {@link org.zkoss.zul.A}. * * @see #isChildAllowedInTextAs * @since 3.0.0 */ public String getTextAs(); /** Returns if a child is allowed in the text-as area. * It is meaningful only if {@link #getTextAs} is not null. * If true, the text enclosed within the element is considered as * text only if there is no other XML element. *

For example, <div> in the following example won't * be considered as text. Rather, a div component will be created. *

<a>
	 *  <div>...</div>
	 *</a>
* *

Default: false. * @see #getTextAs * @since 6.0.0 */ public boolean isChildAllowedInTextAs(); /** Returns whether to preserve the blank text. * If false, the blank text (a non-empty string consisting of whitespaces) * are ignored. * If true, they are converted to a label child. *

Default: false. * @since 3.5.0 */ public boolean isBlankPreserved(); /** Returns whether this is a macro component. * @see #getMacroURI */ public boolean isMacro(); /** Returns the macro URI, or null if not a macro. */ public String getMacroURI(); /** Returns whether this is an inline macro. * If false, you have to examine {@link #isMacro} to see whether it * is a regular macro. */ public boolean isInlineMacro(); /** Returns whether this is used for the native namespace. * * @since 3.0.0 * @see LanguageDefinition#getNativeDefinition */ public boolean isNative(); /** Returns whether this is a shadow element. * * @since 8.0.0 * @see LanguageDefinition#getShadowDefinition */ public boolean isShadowElement(); /** Returns the class (Class) or the class name (String) that * implements the component. * *

If a string is returned, the real class may depend on * which page a component will be created to. * Reason: the zscript interpreter is associated with a page and * it may define classes upon evaluating a page. */ public Object getImplementationClass(); /** Sets the class to implements the component. * *

Note: currently, classes specified in lang.xml or lang-addon.xml * must be resolved when loading the files. * However, classes specified in a page (by use of class or use attributes) * might be resolved later because it might be defined by zscript. */ public void setImplementationClass(Class cls); /** Sets the class name to implements the component. * Unlike {@link #setImplementationClass(Class)}, the class won't * be resolved until {@link ComponentInfo#newInstance} or {@link #getImplementationClass} * is used. In other words, the class can be provided later * (thru, usually, zscript). */ public void setImplementationClass(String clsnm); /** Resolves and returns the class that implements the component. * *

Unlike {@link #getImplementationClass}, * this method will resolve a class name (String) to a class (Class), * if necessary. * In addition, if the clsnm argument is specified, * it is used instead of {@link #getImplementationClass}. * In other words, it overrides the default class. * * @param clsnm [optional] If specified, clsnm is used instead of * {@link #getImplementationClass}. * In other words, it overrides the default class. * @param page the page to check whether the class is defined * in its interpreters. Ignored if null. * This method will search the class loader of the current thread. * If not found, it will search the interpreters of the specified * page ({@link Page#getLoadedInterpreters}). * Note: this method won't attach the component to the specified page. * @exception ClassNotFoundException if the class not found */ public Class resolveImplementationClass(Page page, String clsnm) throws ClassNotFoundException; /** Returns whether a component belongs to this definition. * *

If {@link #resolveImplementationClass} failed to resolve, * true is returned! */ public boolean isInstance(Component comp); /** Creates an component of this definition. * *

Note: this method doesn't invoke {@link #applyProperties}. * It is caller's job to apply these properties if necessary. * Since the value of a property might depend on the component tree, * it is better to assign the component with a proper parent * before calling {@link #applyProperties}. * *

Similarly, this method doesn't attach the component to the * specified page. Developers may or may not add it to a page or * a parent. * *

An application developer can invoke * {@link org.zkoss.zk.ui.sys.UiFactory#newComponent} * instead of {@link #newInstance}, since a deployer might * customize the way to create components by providing * an implementation of {@link org.zkoss.zk.ui.sys.UiFactory}. * In additions, it also invokes {@link #applyProperties} * assigning page/parent. * *

On the other hand, this method is 'low-level'. It simply resolves * the implementation class by use of {@link #resolveImplementationClass}, * and then uses it to create an instance. * * @param clsnm [optional] If specified, clsnm is used instead of * {@link #getImplementationClass}. * In other words, it overrides the default class. * @param page the page that is used to resolve the implementation * class. It is used only this definition is associated * with a class name by {@link #setImplementationClass(String)}, * or clsnm is not null. * Note: this method won't attach the component to the specified page. * It can be null if {@link #getImplementationClass} returns a Class * instance, and clsnm is null. * @return the new component (never null) */ public Component newInstance(Page page, String clsnm); /** Creates an component of this definition. * Refer to {@link #newInstance(Page, String)}. They are the same * except this method accepts the class directly, * while {@link #newInstance(Page, String)} invokes * {@link #resolveImplementationClass} to resolve the class first. * * @return the new component (never null) * @since 3.0.2 */ public Component newInstance(Class cls); /** Adds a mold. * * @param name the mold name. * @param widgetClass the widget class (a.k.a., name). * Ignored if null. * @since 5.0.0 (the 2nd argument is the class name of the peer widget) */ public void addMold(String name, String widgetClass); /** Returns the widget class associated with specified mold, * or the default widget class ({@link #getWidgetClass}) if not available. * The returned widget class includes the package name (JavaScript class). * @param comp the component used to evaluate EL expression, if any, * when retrieving the widget class. Ignored if null. * @param moldName the mold name * @since 5.0.4 */ public String getWidgetClass(Component comp, String moldName); /** Returns the default widget class, or null if not available. * @param comp the component used to evaluate EL expression, if any, * when retrieving the widget class. Ignored if null. * @since 5.0.4 */ public String getDefaultWidgetClass(Component comp); /** Sets the default widget class. * @param widgetClass the name of the widget class (JavaScript class), * including the package name. * @since 5.0.0 */ public void setDefaultWidgetClass(String widgetClass); /** Returns whether the specified mold exists. */ public boolean hasMold(String name); /** Returns a readonly collection of the names of the mold. */ public Collection getMoldNames(); /** Adds a property initializer. * It will initialize a component when created with is definition. * * @param name the member name. The component must have a valid setter * for it. * @param value the value. It might contain expressions (${}). */ public void addProperty(String name, String value); /** Applies the properties defined in * this definition to the specified component. * *

Note: annotations are applied to the component when a component * is created. So, this method doesn't and need not to copy them. *

Also notice that, since 5.0.7, custom-attributes are applied automatically * in the constructor of {@link org.zkoss.zk.ui.AbstractComponent#AbstractComponent} * (by invoking {@link #applyAttributes}, * so they are always available no matter this method is called or not. */ public void applyProperties(Component comp); /** Applies the custom attributes defined in this definition * to the specified component. *

It is called automatically in * {@link org.zkoss.zk.ui.AbstractComponent#AbstractComponent}, so * you rarely need to invoke this method. * @since 5.0.7 */ public void applyAttributes(Component comp); /** Evaluates and retrieves properties to the specified map. * * @param propmap the map to store the retrieved properties. * If null, a HashMap instance is created. * (String name, Object value). * @param owner the owner page; used if parent is null * @param parent the parent */ public Map evalProperties(Map propmap, Page owner, Component parent); /** Returns the annotation map defined in this definition, or null * if no annotation is ever defined. */ public AnnotationMap getAnnotationMap(); /** Returns the apply attribute that is a list of *{@link Composer} class * names or EL expressions returning classes, class names or composer * instances, or null if no apply attribute. * * @see #getParsedApply * @since 3.6.0 */ public String getApply(); /** Return the parsed expressions of the apply attribute. * @see #getApply * @since 3.6.0 */ public ExValue[] getParsedApply(); /** Sets the apply attribute that is is a list of {@link Composer} class * or EL expressions returning classes, class names or composer instances. * * @param apply the attribute this is a list of {@link Composer} class * or EL expressions * El expressions are allowed, but self means the parent, if available; * or page, if no parent at all. (Note: the component is not created yet * when the apply attribute is evaluated). * @since 3.6.0 */ public void setApply(String apply); /** Returns the URL where this component definition is declared, or * null if not available. * @since 3.0.3 */ public URL getDeclarationURL(); /** Clones this definition and assigns with the specified language * definition and name. */ public ComponentDefinition clone(LanguageDefinition langdef, String name); /** Clones this component definition. * You rarely invoke this method directly. Rather, use * {@link #clone(LanguageDefinition, String)}. * *

Note: the caller usually has to change the component name, * and then assign to a language definition ({@link LanguageDefinition}) * or a page definition ({@link PageDefinition}). * * @return the new component definition by cloning from this definition. */ public Object clone(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy