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

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

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

	Purpose:
		
	Description:
		
	History:
		3:04:11 PM Oct 23, 2014, Created by jumperchen

Copyright (C) 2014 Potix Corporation. All Rights Reserved.
*/
package org.zkoss.zk.ui.metainfo;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.zkoss.util.resource.Location;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.ext.DynamicTag;
import org.zkoss.zk.ui.sys.ComponentsCtrl;
import org.zkoss.zk.ui.util.ConditionImpl;

/**
 * Represent a shadow element.
 * @author jumperchen
 * @since 8.0.0
 */
public class ShadowInfo extends BranchInfo {
	private ComponentDefinition _compdef;
	/** A list of {@link Property}, or null if no property at all. */
	private List _props;
	private final String _tag;
	/** the annotation map. Note: it doesn't include what are defined in _compdef. */
	private AnnotationMap _annots;
	//F80 - store subtree's binder annotation count
	private boolean _hasBindingAnnotation = false;

	private boolean _isAnnotationNamespacedRoot = false;

	/** Creates a shadow.
	 *
	 * @param parent the parent node (never null)
	 * @param compdef the component definition; never null
	 * @param tag the tag name; Note: if component implements
	 * {@link DynamicTag}, this argument must be specified.
	 * If {@link DynamicTag} is not implemented, this argument is optional.
	 */
	public ShadowInfo(NodeInfo parent, ComponentDefinition compdef, String tag, ConditionImpl cond) {
		super(parent, cond);
		_tag = tag;
		if (compdef == null)
			throw new IllegalArgumentException();
		_compdef = compdef;
	}

	/** Returns the annotation map defined in this info, or null
	 * if no annotation is ever defined.
	 */
	public AnnotationMap getAnnotationMap() {
		return _annots;
	}

	/** Applies the event handlers and properties to the specified component.
	 *
	 * 

It also invokes {@link ComponentDefinition#applyProperties}. * *

Note: annotations are applied to the component when a component * is created. So, this method doesn't and need not to copy them. * See also {@link org.zkoss.zk.ui.AbstractComponent#AbstractComponent}. * */ public void applyProperties(Component comp) { _compdef.applyProperties(comp); } /** Adds an annotation to the specified property of this component * info. * * @param propName the property name. * If null, the annotation is associated with the whole component rather than * a particular property. * @param annotName the annotation name (never null, nor empty). * @param annotAttrs a map of attributes, or null if no attribute at all. * The attribute must be in a pair of strings (String name, String value), * or (String name, String[] value). * @param loc the location information of the annotation in * the document, or null if not available. */ public void addAnnotation(String propName, String annotName, Map annotAttrs, Location loc) { if (_annots == null) _annots = new AnnotationMap(); _annots.addAnnotation(propName, annotName, annotAttrs, loc); } /** Applies the custom attributes. *

Note: this method does nothing if {@link #isEffective} returns false. */ public void apply(Component comp) { if (_props != null && isEffective(comp)) { for (Property prop : _props) { prop.assign(comp); } } } /** Creates a shadow element based on this info (never null). * It is the same as newInstance(page, null). * *

If the implementation class doesn't have any EL expression, * or its EL expression doesn't have reference to the self variable, * the result is the same. * *

This method is preserved for backward compatibility. * It is better to use {@link #newInstance(Page, Component)}. */ public Component newInstance(Page page) { return newInstance(page, null); } /** Creates an component based on this info (never null). * *

Like {@link ComponentDefinition#newInstance}, * this method doesn't invoke {@link #applyProperties}. * It is caller's job to invoke them if necessary. * Since the value of properties might depend on the component tree, * it is better to assign the component with a proper parent * before calling {@link #applyProperties}. * */ public Component newInstance(Page page, Component parent) { ComponentsCtrl.setCurrentInfo(this); final Component comp; try { comp = _compdef.newInstance(page, null); // use the default one } catch (Exception ex) { throw UiException.Aide.wrap(ex); } finally { ComponentsCtrl.setCurrentInfo((ComponentInfo) null); } return comp; } /** Returns the language definition that {@link #getComponentDefinition} * belongs to, or null if the component definition is temporary. */ public LanguageDefinition getLanguageDefinition() { return _compdef.getLanguageDefinition(); } /** Returns the component definition, or null if it is PageDefinition. */ public ComponentDefinition getComponentDefinition() { return _compdef; } /** Returns a readonly list of properties ({@link Property}) (never null). */ public List getProperties() { if (_props != null) return _props; return Collections.emptyList(); //it is better to protect with Collections.unmodifiableList //but for better performance... } /** Adds a property initializer. * It will initialize a component when created with this info. * @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, ConditionImpl cond) { if (name == null || name.length() == 0) throw new IllegalArgumentException("name cannot be empty"); if (_props == null) _props = new LinkedList(); _props.add(new Property(_evalr, name, value, cond)); } /** Adds a child. * * @exception IllegalStateException if this is not an instance of * {@link TemplateInfo} and {@link ShadowInfo}. */ public void appendChild(NodeInfo child) { if (!((child instanceof ShadowInfo) || (child instanceof TemplateInfo))) throw new IllegalStateException("Only accept template and shadow element to be a child of " + this); super.appendChild(child); } //Object// public String toString() { final StringBuffer sb = new StringBuffer(40).append("[shadow element(").append(_tag).append(")"); if (_props != null) for (Property name : _props) sb.append(' ').append(name.getName()); return sb.append(']').toString(); } //F80 - store subtree's binder annotation count public boolean hasBindingAnnotation() { return _hasBindingAnnotation; } public void enableBindingAnnotation() { this._hasBindingAnnotation = true; } public void disableBindingAnnotation() { this._hasBindingAnnotation = false; } /** * @return whether this ShadowInfo is the first ShadowInfo that has annotation namespace or binding annotation. * @since 8.5.2 */ public boolean isAnnotationNamespacedRoot() { return _isAnnotationNamespacedRoot; } /** * Sets whether this ShadowInfo is the first ShadowInfo that has annotation namespace or binding annotation. * @param annotationNamespacedRoot * @since 8.5.2 */ public void setAnnotationNamespacedRoot(boolean annotationNamespacedRoot) { _isAnnotationNamespacedRoot = annotationNamespacedRoot; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy