/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// XmlXulRuleSet.java
package nonjsp.application;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.component.UIOutput;
import org.apache.commons.digester.AbstractObjectCreationFactory;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.RuleSetBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;
import nonjsp.util.Util;
/**
* <p>The set of Digester rules required to parse a Faces Xul (Xml)
* configuration file.
*/
public class XmlXulRuleSet extends RuleSetBase {
// Log instance for this class
protected static Log log = LogFactory.getLog(XmlXulRuleSet.class);
private BuildComponentFromTag buildComponent = null;
/**
* Constructor sets Faces modules needed for building
* UIComponent instances.
*/
public XmlXulRuleSet(BuildComponentFromTag bc) {
buildComponent = bc;
}
/**
* <p>Add the set of Rule instances defined in this RuleSet to the
* specified <code>Digester</code> instance.
*
* @param digester Digester instance to which the new Rule instances
* should be added.
*/
public void addRuleInstances(Digester digester) {
digester.addCallMethod("*/page-url", "setPageUrl", 0);
digester.addObjectCreate("*/window", "javax.faces.component.UIForm");
digester.addObjectCreate("*/label", "javax.faces.component.UIOutput");
digester.addObjectCreate("*/textbox", "javax.faces.component.UIInput");
digester.addObjectCreate("*/checkbox",
"javax.faces.component.UISelectBoolean");
digester.addObjectCreate("*/radiogroup",
"javax.faces.component.UISelectOne");
digester.addObjectCreate("*/menupopup",
"javax.faces.component.UISelectOne");
digester.addObjectCreate("*/link", "javax.faces.component.UICommand");
/*
* Button no longer needs an ActionRule that creates a default
* ActionListener because the API's UICommandBase now installs
* a default ActionListener
*/
digester.addObjectCreate("*/button", "javax.faces.component.UICommand");
digester.addObjectCreate("*/image", "javax.faces.component.UIGraphic");
digester.addFactoryCreate("*/uicomponent", new UIComponentFactory());
ComponentRule cRule = new ComponentRule();
cRule.setBuildComponent(buildComponent);
digester.addRule("*/window", cRule);
digester.addRule("*/label", cRule);
digester.addRule("*/textbox", cRule);
digester.addRule("*/checkbox", cRule);
digester.addRule("*/radiogroup", cRule);
digester.addRule("*/menupopup", cRule);
digester.addRule("*/link", cRule);
digester.addRule("*/button", cRule);
digester.addRule("*/image", cRule);
ComponentNestedRule cnRule = new ComponentNestedRule();
cnRule.setBuildComponent(buildComponent);
digester.addRule("*/radio", cnRule);
digester.addRule("*/menuitem", cnRule);
}
}
final class UIComponentFactory extends AbstractObjectCreationFactory {
public Object createObject(Attributes attributes) {
Class cClass = null;
UIComponent c = null;
// Identify the name of the class to instantiate
String className = attributes.getValue("class");
String id = attributes.getValue("id");
String value = attributes.getValue("value");
// Instantiate the new object and return it
try {
cClass = Util.loadClass(className);
c = (UIComponent) cClass.newInstance();
} catch (ClassNotFoundException cnf) {
throw new RuntimeException("Class Not Found:" + cnf.getMessage());
} catch (InstantiationException ie) {
throw new RuntimeException("Class Instantiation Exception:" +
ie.getMessage());
} catch (IllegalAccessException ia) {
throw new RuntimeException("Illegal Access Exception:" +
ia.getMessage());
}
c.setId(id);
if (c instanceof UIOutput) {
((UIOutput) c).setValue(value);
}
return c;
}
}
final class ComponentRule extends Rule {
// Log instance for this class
protected static Log log = LogFactory.getLog(ComponentRule.class);
private BuildComponentFromTag bc;
private UIComponent root;
public ComponentRule() {
super();
root = null;
}
/**
* This method is invoked when the beginning of the matched
* Xml element is encountered ;
*
* @param attributes The element's attribute list
*/
public void begin(Attributes attributes) throws Exception {
UIComponent uic = (UIComponent) digester.peek();
if (log.isTraceEnabled()) {
log.trace("component: " + uic.getId());
}
AttributesImpl attrs = new AttributesImpl(attributes);
for (int i = 0; i < attrs.getLength(); i++) {
String qName = attributes.getQName(i);
attrs.setLocalName(i, qName);
attrs.setValue(i, attributes.getValue(qName));
if (log.isTraceEnabled()) {
log.trace(
"ComponentRule: qName: " + qName + " value: " +
attributes.getValue(qName));
}
}
bc.applyAttributesToComponentInstance(uic, attrs);
if (root == null) {
root = (UIComponent) digester.peek(digester.getCount() - 1);
}
root.getChildren().add(uic);
//If component is a form, make it the root so that children will be
//added to it
if (uic instanceof UIForm) {
root = uic;
}
}
/**
* This method is invoked when the end of the matched
* Xml element is encountered ;
*
* @param attributes The element's attribute list
*/
public void end(String namespace, String name) {
//Reset the root
UIComponent uic = (UIComponent) digester.peek();
if (uic instanceof UIForm) {
root = (UIComponent) digester.peek(digester.getCount() - 1);
}
}
public void setBuildComponent(BuildComponentFromTag bc) {
this.bc = bc;
}
}
/**
* This processing rule translates nested element names and values
* (as in Faces "SelectOne" component items.
* The attributes are set on the UIComponent instance.
*/
final class ComponentNestedRule extends Rule {
private BuildComponentFromTag bc;
public ComponentNestedRule() {
super();
}
/**
* This method is invoked when the beginning of the matched
* Xml element is encountered (in this case "property");
*
* @param attributes The element's attribute list
*/
public void begin(Attributes attributes) throws Exception {
UIComponent uic = (UIComponent) digester.peek();
AttributesImpl attrs = new AttributesImpl(attributes);
for (int i = 0; i < attrs.getLength(); i++) {
String qName = attributes.getQName(i);
attrs.setLocalName(i, qName);
attrs.setValue(i, attributes.getValue(qName));
}
bc.handleNestedComponentTag(uic, "SelectOne_Option", attrs);
}
public void setBuildComponent(BuildComponentFromTag bc) {
this.bc = bc;
}
}