diff --git a/jsft/pom.xml b/jsft/pom.xml new file mode 100644 index 0000000..0acf67a --- /dev/null +++ b/jsft/pom.xml @@ -0,0 +1,98 @@ + + + + + 4.0.0 + + com.sun.jsftemplating + jsftemplating-parent + 2.1.1-SNAPSHOT + + jsft + + + + + org.apache.felix + maven-bundle-plugin + + + bundle-manifest + process-classes + + manifest + + + *;version="${project.osgi.version}" + + com.sun.jsft.commands;version="${project.osgi.version}", + com.sun.jsft.event;version="${project.osgi.version}", + com.sun.jsft.facelets;version="${project.osgi.version}", + com.sun.jsft.util;version="${project.osgi.version}", + javax.el;version="[2.1.2,3.0)", + javax.faces;version="[2.0.0,3.0)", + javax.faces.application;version="[2.0.0,3.0)", + javax.faces.bean;version="[2.0.0,3.0)", + javax.faces.component;version="[2.0.0,3.0)", + javax.faces.context;version="[2.0.0,3.0)", + javax.faces.event;version="[2.0.0,3.0)", + javax.faces.view.facelets;version="[2.0.0,3.0)",* + + + + + + + + + + + javax.faces + javax.faces-api + + + javax.el + el-api + + + diff --git a/jsft/src/main/java/com/sun/jsft/commands/JSFTCommands.java b/jsft/src/main/java/com/sun/jsft/commands/JSFTCommands.java new file mode 100644 index 0000000..05bd4b5 --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/commands/JSFTCommands.java @@ -0,0 +1,218 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +/** + * UtilCommands.java + * + * Created April 2, 2011 + * @author Ken Paulsen (kenapaulsen@gmail.com) + */ +package com.sun.jsft.commands; + +import com.sun.jsft.event.Command; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; +import java.util.Map; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ApplicationScoped; +import javax.faces.context.FacesContext; + + +/** + *

This class contains methods that perform common utility-type + * functionality.

+ * + * @author Ken Paulsen (kenapaulsen@gmail.com) + */ +@ApplicationScoped +@ManagedBean(name="jsft") +public class JSFTCommands { + + /** + *

Default Constructor.

+ */ + public JSFTCommands() { + } + + /** + *

This command conditionally executes its child commands.

+ */ + public void _if(boolean condition) { + Command command = (Command) FacesContext.getCurrentInstance(). + getExternalContext().getRequestMap().get(Command.COMMAND_KEY); + if (condition) { + command.invokeChildCommands(); + } else { + command = command.getElseCommand(); + if (command != null) { + command.invoke(); + } + } + } + + /** + *

This command iterates over the given List and sets given + */ + public void foreach(String var, List list) { + // Get the Request Map + Map reqMap = FacesContext.getCurrentInstance(). + getExternalContext().getRequestMap(); + + // Get the Current Command... + Command command = (Command) reqMap.get(Command.COMMAND_KEY); + + // Iterate over each item in the List + List childCommands = null; + for (Object item : list) { + // Set the item in the request scope under the given key + reqMap.put(var, item); + + // Invoke all the child commands + childCommands = command.getChildCommands(); + if (childCommands != null) { + for (Command childCommand : childCommands) { + childCommand.invoke(); + } + } + } + } + + + /** + *

This command sets a requestScope attribute with the given + * key and value.

+ */ + public void setAttribute(String key, Object value) { + FacesContext.getCurrentInstance().getExternalContext(). + getRequestMap().put(key, value); + } + + /** + *

This command writes output using System.out.println. + * It requires value to be supplied.

+ */ + public void println(String value) { + System.out.println(value); + } + + /** + *

This command writes using + * FacesContext.getResponseWriter().

+ * + * @param context The HandlerContext. + */ + public static void write(String text) { + if (text == null) { + text = ""; + } + try { + FacesContext.getCurrentInstance().getResponseWriter().write(text); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + /** + *

This command marks the response complete. This means that no + * additional response will be sent. This is useful if you've + * provided a response already and you don't want JSF to do it again + * (it may cause problems to do it 2x).

+ * + * @param context The HandlerContext. + */ + public static void responseComplete() { + FacesContext.getCurrentInstance().responseComplete(); + } + + /** + *

This command indicates to JSF that the request should proceed + * immediately to the render response phase. It will be ignored if + * rendering has already begun. This is useful if you want to stop + * processing and jump to the response. This is often the case when + * an error ocurrs or validation fails. Typically the page the user + * is on will be reshown (although if navigation has already + * occurred, the new page will be shown.

+ * + * @param context The HandlerContext. + */ + public void renderResponse() { + FacesContext.getCurrentInstance().renderResponse(); + } + + /** + *

This command provides a way to see the call stack by printing a + * stack trace. The output will go to stderr and will also be + * returned in the output value "stackTrace". An optional message + * may be provided to be included in the trace.

+ */ + public void printStackTrace(String msg) { + // See if we have a message to print w/ it + if (msg == null) { + msg = ""; + } + + // Get the StackTrace + StringWriter strWriter = new StringWriter(); + new RuntimeException(msg).printStackTrace(new PrintWriter(strWriter)); + String trace = strWriter.toString(); + + // Print it to stderr and return it + System.err.println(trace); + } + + /** + *

Returns the nano seconds since some point in time. This is only + * useful for relative measurments.

+ */ + public long getNanoTime() { + return nanoStartTime - System.nanoTime(); + } + + /** + *

This is application scoped, so it is not safe to change. Use + * caution.

+ */ + private long nanoStartTime = System.nanoTime(); +} diff --git a/jsft/src/main/java/com/sun/jsft/commands/UtilCommands.java b/jsft/src/main/java/com/sun/jsft/commands/UtilCommands.java new file mode 100644 index 0000000..8d03ee3 --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/commands/UtilCommands.java @@ -0,0 +1,302 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +/** + * UtilCommands.java + * + * Created March 29, 2011 + * @author Ken Paulsen kenapaulsen@gmail.com + */ +package com.sun.jsft.commands; + +import java.util.Iterator; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ApplicationScoped; + + +/** + *

This class contains methods that perform common utility-type + * functionality.

+ * + * @author Ken Paulsen (kenapaulsen@gmail.com) + */ +@ApplicationScoped +@ManagedBean(name="util") +public class UtilCommands { + + /** + *

Default Constructor.

+ */ + public UtilCommands() { + } + + /** + *

This command prints out the contents of the given + * UIComponent's attribute map.

+ */ + public void dumpAttributeMap(UIComponent comp) { + if (comp != null) { + Map map = comp.getAttributes(); + for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { + Map.Entry me = (Map.Entry)iter.next(); + System.out.println("key="+ me.getKey()+"'"+"value="+ me.getValue()); + } + } else { + System.out.println("UIComponent is null"); + } + } + + /** + *

This method returns an Iterator for the given + * List. The List input value key is: + * "list". The output value key for the Iterator is: + * "iterator".

+ * + * @param context The HandlerContext. + @Handler(id="getIterator", + input={ + @HandlerInput(name="list", type=List.class, required=true)}, + output={ + @HandlerOutput(name="iterator", type=Iterator.class)}) + public static void getIterator(HandlerContext context) { + List list = (List) context.getInputValue("list"); + context.setOutputValue("iterator", list.iterator()); + } + */ + + /** + *

This method returns a Boolean value representing + * whether another value exists for the given Iterator. + * The Iterator input value key is: "iterator". The + * output value key is "hasNext".

+ * + * @param context The HandlerContext. + @Handler(id="iteratorHasNext", + input={ + @HandlerInput(name="iterator", type=Iterator.class, required=true)}, + output={ + @HandlerOutput(name="hasNext", type=Boolean.class)}) + public static void iteratorHasNext(HandlerContext context) { + Iterator it = (Iterator) context.getInputValue("iterator"); + context.setOutputValue("hasNext", Boolean.valueOf(it.hasNext())); + } + */ + + /** + *

This method returns the next object in the List that + * the given Iterator is iterating over. The + * Iterator input value key is: "iterator". The + * output value key is "next".

+ * + * @param context The HandlerContext. + @Handler(id="iteratorNext", + input={ + @HandlerInput(name="iterator", type=Iterator.class, required=true)}, + output={ + @HandlerOutput(name="next")}) + public static void iteratorNext(HandlerContext context) { + Iterator it = + (Iterator) context.getInputValue("iterator"); + context.setOutputValue("next", it.next()); + } + */ + + /** + *

This method creates a List. Optionally you may supply "size" to + * create a List of blank "" values of the specified size. The + * output value from this command is "result".

+ * + * @param context The HandlerContext + @Handler(id="createList", + input={ + @HandlerInput(name="size", type=Integer.class, required=true)}, + output={ + @HandlerOutput(name="result", type=List.class)}) + public static void createList(HandlerContext context) { + int size = ((Integer) context.getInputValue("size")).intValue(); + List list = new ArrayList(size); + for (int count = 0; count < size; count++) { + list.add(""); + } + context.setOutputValue("result", list); + } + */ + + /** + *

This method creates a Map (HashMap). + * The output value from this command is "result".

+ * + * @param context The HandlerContext + @Handler(id="createMap", + output={ + @HandlerOutput(name="result", type=Map.class)}) + public static void createMap(HandlerContext context) { + Map map = new HashMap(); + context.setOutputValue("result", map); + } + */ + + /** + *

This method adds a value to a Map. You must supply + * map to use as well as the key and + * value to add.

+ * + * @param context The HandlerContext + @Handler(id="mapPut", + input={ + @HandlerInput(name="map", type=Map.class, required=true), + @HandlerInput(name="key", type=Object.class, required=true), + @HandlerInput(name="value", type=Object.class, required=true)} + ) + public static void mapPut(HandlerContext context) { + Map map = (Map) context.getInputValue("map"); + Object key = context.getInputValue("key"); + Object value = context.getInputValue("value"); + map.put(key, value); + } + */ + + /** + *

This command url-encodes the given String. It will return null if + * null is given and it will use a default encoding of "UTF-8" if no + * encoding is specified.

+ * + * @param context The HandlerContext. + @Handler(id="urlencode", + input={ + @HandlerInput(name="value", type=String.class, required=true), + @HandlerInput(name="encoding", type=String.class) + }, + output={ + @HandlerOutput(name="result", type=String.class)}) + public static void urlencode(HandlerContext context) { + String value = (String) context.getInputValue("value"); + String encoding = (String) context.getInputValue("encoding"); + if (encoding == null) { + encoding = "UTF-8"; + } + // The value could be null if an EL expression maps to null + if (value != null) { + try { + value = java.net.URLEncoder.encode(value, encoding); + } catch (java.io.UnsupportedEncodingException ex) { + throw new IllegalArgumentException(ex); + } + } + context.setOutputValue("result", value); + } + */ + + /** + *

This command gets the current system time in milliseconds. It may + * be used to time things.

+ @Handler(id="getDate", + output={ + @HandlerOutput(name="time", type=Long.class) + }) + public static void getDate(HandlerContext context) { + context.setOutputValue("time", new java.util.Date().getTime()); + } + */ + + /** + *

This method converts '<' and '>' characters into "&lt;" + * and "&gt;" in an effort to avoid HTML from being processed. + * This can be used to avoid <script> tags, or to show code + * examples which might include HTML characters. '&' characters + * will also be converted to "&amp;".

+ @Handler(id="htmlEscape", + input={ + @HandlerInput(name="value", type=String.class, required=true) + }, + output={ + @HandlerOutput(name="result", type=String.class)}) + public static void htmlEscape(HandlerContext context) { + String value = (String) context.getInputValue("value"); + value = com.sun.jsft.util.Util.htmlEscape(value); + context.setOutputValue("result", value); + } + */ + + /** + *

A utility command that resembles the for() method in Java. Commands + * inside the for loop will be executed in a loop. The starting index + * is specified by start. The index will increase + * sequentially untill it is equal to end. + * var will be a request attribute that is set to the + * current index value as the loop iterates.

+ *

For example:

+ * + * forLoop(start="1" end="3" var="foo") {...} + * + *

The commands inside the {...} will be executed 2 times + * (with foo=1 and foo=2).

+ * + *
  • start -- type: Integer Starting + * index, defaults to zero if not specified.
  • + *
  • end -- type: Integer; Ending index. + * Required.
  • + *
  • var -- type: String; Request + * attribute to be set in the for loop to the value of the + * index.
+ public static boolean forLoop(int start, int end, String var) { + List<> commands = + handlerCtx.getHandler().getChildHandlers(); + if (commands.size() > 0) { + // We have child commands in the loop... execute while we iterate + Map requestMap = FacesContext.getCurrentInstance(). + getExternalContext().getRequestMap(); + for (int idx=start; idx < end; idx++) { + requestMap.put(var, idx); + // Ignore what is returned by the commands... we need to return + // false anyway to prevent children from being executed again + elt.dispatchHandlers(commands); + } + } + + // This will prevent the child commands from executing again + return false; + } + */ +} diff --git a/jsft/src/main/java/com/sun/jsft/component/DeferredFragment.java b/jsft/src/main/java/com/sun/jsft/component/DeferredFragment.java new file mode 100644 index 0000000..1ad70ce --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/component/DeferredFragment.java @@ -0,0 +1,343 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +package com.sun.jsft.component; + +import com.sun.jsft.tasks.Task; +import com.sun.jsft.tasks.TaskEvent; +import com.sun.jsft.tasks.TaskManager; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import javax.faces.component.UIComponent; +import javax.faces.component.UIComponentBase; +import javax.faces.component.UIOutput; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.event.AbortProcessingException; +import javax.faces.event.ComponentSystemEvent; +import javax.faces.event.ComponentSystemEventListener; +import javax.faces.event.PostAddToViewEvent; +import javax.faces.event.SystemEvent; +import javax.faces.event.SystemEventListener; + + +/** + * + */ +public class DeferredFragment extends UIComponentBase { + + /** + *

Default constructor.

+ */ + public DeferredFragment() { + subscribeToEvent( + PostAddToViewEvent.class, + new DeferredFragment.AfterCreateListener()); + } + + /** + * + */ + public String getFamily() { + return FAMILY; + } + + /** + * + */ + public boolean getRendersChildren() { + return true; + } + + public void encodeBegin(FacesContext context) throws IOException { + System.out.println("Encode Begin ("+getId()+")..."); + } + + public void encodeEnd(FacesContext context) throws IOException { + System.out.println("Encode End ("+getId()+")..."); + } + + /** + *

This method returns true when all tasks this deferred + * fragment depends on are complete. This method is not intended to + * be used to poll this task for completion, you should instead + * register for the ready event that it fires.

+ */ + private boolean isReady() { + return (taskCount == 0); + } + + /** + *

This method gets the id of the "place-holder" component for this + * DeferredFragment.

+ */ + public String getPlaceHolderId() { + return placeHolderId; + } + + /** + *

This method sets the id of the "place-holder" component for this + * DeferredFragment.

+ */ + public void setPlaceHolderId(String id) { + placeHolderId = id; + } + + /** + *

This method returns the number of tasks this DeferredFragment is + * waiting for.

+ */ + public int getTaskCount() { + return taskCount; + } + + /** + *

This method sets the number of tasks this + * DeferredFragment must wait for.

+ */ + public void setTaskCount(int count) { + taskCount = count; + } + + /** + *

This method registers the given + * ComponentSystemEventListener that should be notified + * when this DeferredFragment is ready to be + * rendered.

+ */ + public void addReadyListener(ComponentSystemEventListener listener) { + listeners.add(listener); + } + + /** + *

This method is responsible for firing the {@link FragmentReadyEvent} + * to signal to listeners that the {@link Task}s needed by this + * DeferredFragment have completed and it is now ready to + * be processed.

+ */ + protected void fireFragmentReadyEvent() { + ComponentSystemEvent event = new FragmentReadyEvent(this); +System.out.println("listeners" + listeners); + for (ComponentSystemEventListener listener : listeners) { + listener.processEvent(event); + } + } + + + /** + *

Listener used to handle TaskEvents.

+ */ + public static class DeferredFragmentTaskListener implements SystemEventListener { + + /** + *

Default Constructor.

+ */ + public DeferredFragmentTaskListener(DeferredFragment df) { + super(); + this.df = df; + } + + /** + *

The event passed in will be a {@link TaskEvent}.

+ */ + public void processEvent(SystemEvent event) throws AbortProcessingException { +System.out.println("DeferredFragmentTaskListener.processEvent()!"); + Task task = (Task) event.getSource(); + String eventType = ((TaskEvent) event).getType(); + int count = 0; + synchronized (df) { + // Synch to ensure we don't change it during this time. + count = df.getTaskCount() - 1; + df.setTaskCount(count); + } + if (count == 0) { + // We're done! + df.fireFragmentReadyEvent(); + } + } + + public boolean isListenerForSource(Object source) { + // We only dispatch this correctly... this method is not needed. + return true; + } + + // A reference to the DeferredFragment + private DeferredFragment df = null; + } + + /** + *

Listener used to relocate the children to a facet on the + * UIViewRoot.

+ */ + public static class AfterCreateListener implements ComponentSystemEventListener { + AfterCreateListener() { + } + + /** + *

This method is responsible for setting up this + * DeferredFragment. This includes the following + * steps:

+ * + *
  • Put a "place-holder" component at the location of the + * fragment so it can be swapped out by the client at a later + * time.
  • + *
  • Move this component to a facet in the UIViewRoot.
  • + *
  • Register any tasks that need to be executed, add a listener + * for each task or the specified event within the task.
  • + *
  • Ensure a FragmentRenderer component exists at the end of the page.
  • + */ + public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { + // Ensure we only do this once... NOTE: I tried to unsubscribe from + // the event, but ran into a ConcurrentModificationException... the + // list of listeners is probably still being looped through while I + // am attempting to remove this Listener. So I'll do this instead: + if (done) { + return; + } + done = true; + + // Get the component + DeferredFragment comp = (DeferredFragment) event.getComponent(); + + // Get the UIViewRoot Facet Map + FacesContext ctx = FacesContext.getCurrentInstance(); + UIViewRoot viewRoot = ctx.getViewRoot(); + Map facetMap = viewRoot.getFacets(); + + // Create a place holder... + String key = "jsft_" + comp.getClientId(ctx); + UIComponent placeHolder = new UIOutput(); + placeHolder.getAttributes().put( + "value", ""); + + // Swap comp with the placeHolder... + List peers = comp.getParent().getChildren(); + int index = peers.indexOf(comp); + peers.set(index, placeHolder); + comp.setPlaceHolderId(placeHolder.getClientId(ctx)); + + // Move this component to the FacetMap + facetMap.put(key, comp); + + // Register task(s) + String task = (String) comp.getAttributes().get("task"); + StringTokenizer tok = new StringTokenizer(task, ";"); + TaskManager tm = TaskManager.getInstance(); + int taskCount = 0; + while (tok.hasMoreTokens()) { + task = tok.nextToken().trim(); + + // Check to see if we have task:listenerType + int idx = task.indexOf(":"); + String type = null; + if (idx != -1) { + type = task.substring(idx + 1); + task = task.substring(0, idx); + } + + // Register the Task... + tm.addTask(task, type, new DeferredFragmentTaskListener(comp)); + + // Count the tasks we depend on... + taskCount++; + } + + // Store the task count... + comp.setTaskCount(taskCount); + + // Ensure we have a FragmentRenderer component... + Map requestScope = + ctx.getExternalContext().getRequestMap(); + FragmentRenderer fragmentRenderer = + (FragmentRenderer) requestScope.get(FRAGMENT_RENDERER); + if (fragmentRenderer == null) { + // Create one... + fragmentRenderer = new FragmentRenderer(); + fragmentRenderer.setId(FRAGMENT_RENDERER); + + // Store FragmentRenderer in request scope as well as the last + // component in the UIViewRoot. (request scope for fast access) + viewRoot.getChildren().add(fragmentRenderer); + requestScope.put(FRAGMENT_RENDERER, fragmentRenderer); + } + + // Increment fragment count on FragmentRenderer component... + fragmentRenderer.addDeferredFragment(comp); + comp.addReadyListener(fragmentRenderer); + } + + private boolean done = false; + private static final String FRAGMENT_RENDERER = "jsft-FR"; + } + + /** + *

    The component family.

    + */ + public static final String FAMILY = DeferredFragment.class.getName(); + + + /** + *

    The number of tasks that need to be complete before this + * DeferredFragment can be rendered. It is initialized + * to a postiive value (1) so that {@link #isReady()} will return + * false -- important since the tasks have not yet been + * counted.

    + */ + private int taskCount = 1; + + /** + *

    The id of the placeholder for this component so we can find it + * later.

    + */ + private transient String placeHolderId = ""; + + /** + *

    This List will hold the list of listeners interested + * in being notified with this DeferredFragment is ready + * to be rendered.

    + */ + private List listeners = + new ArrayList(2); +} diff --git a/jsft/src/main/java/com/sun/jsft/component/FragmentReadyEvent.java b/jsft/src/main/java/com/sun/jsft/component/FragmentReadyEvent.java new file mode 100644 index 0000000..018d19b --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/component/FragmentReadyEvent.java @@ -0,0 +1,58 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +package com.sun.jsft.component; + +import javax.faces.event.ComponentSystemEvent; + + +/** + *

    This event is used for dispatching {@link Task} related events.

    + */ +public class FragmentReadyEvent extends ComponentSystemEvent { + + /** + *

    Constructor.

    + */ + public FragmentReadyEvent(DeferredFragment source) { + super(source); + } +} diff --git a/jsft/src/main/java/com/sun/jsft/component/FragmentRenderer.java b/jsft/src/main/java/com/sun/jsft/component/FragmentRenderer.java new file mode 100644 index 0000000..06c6d26 --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/component/FragmentRenderer.java @@ -0,0 +1,198 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +package com.sun.jsft.component; + +import com.sun.jsft.tasks.TaskManager; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.StringTokenizer; +import java.util.concurrent.ConcurrentLinkedQueue; +import javax.faces.component.UIComponent; +import javax.faces.component.UIComponentBase; +import javax.faces.component.UIOutput; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.event.AbortProcessingException; +import javax.faces.event.ComponentSystemEvent; +import javax.faces.event.ComponentSystemEventListener; +import javax.faces.event.ListenerFor; +import javax.faces.event.PostAddToViewEvent; + + +/** + * + */ +public class FragmentRenderer extends UIComponentBase implements ComponentSystemEventListener { + + /** + *

    Default constructor.

    + */ + public FragmentRenderer() { + } + + /** + * + */ + public String getFamily() { + return FAMILY; + } + + /** + * + */ + public boolean getRendersChildren() { + return true; + } + + public void encodeBegin(FacesContext context) throws IOException { + System.out.println("Starting FragmentRenderer..."); + // Start processing the Tasks... + TaskManager.getInstance().start(); + } + + public void encodeChildren(FacesContext context) throws IOException { + // It should have no children... do nothing... + } + + public void encodeEnd(FacesContext context) throws IOException { + // Render fragments as they become ready. + fragsToRender = getFragmentCount(); + DeferredFragment comp = null; + while (fragsToRender > 0) { + synchronized (renderQueue) { + if (renderQueue.isEmpty()) { + try { + // Wait at most 30 seconds... + renderQueue.wait(30 * 1000); + if (renderQueue.isEmpty()) { + System.out.println("EMPTY QUEUE!"); + return; + } + } catch (InterruptedException ex) { + System.out.println("Interrupted!"); + return; + } + } + comp = renderQueue.poll(); + } + if (comp != null) { + fragsToRender--; + try { +System.out.println("Encoding: " + comp.getId()); + comp.encodeAll(FacesContext.getCurrentInstance()); + } catch (Exception ex) { + // FIXME: cleanup + ex.printStackTrace(); + } + } + } + + System.out.println("Ending FragmentRenderer..." + fragsToRender); + } + + /** + *

    This method returns the number of tasks this DeferredFragment is + * waiting for.

    + */ + public int getFragmentCount() { + return fragments.size(); + } + + /** + *

    This method adds the given {@link DeferredFragment} to the + * List of fragments that are to be processed by this + * FragmentRenderer.

    + */ + public void addDeferredFragment(DeferredFragment fragment) { + fragments.add(fragment); + } + + + /** + *

    This method gets invoked whenever a DeferredFragment associated + * with this component becomes ready to be rendered.

    + */ + public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { + // Get the component + processDeferredFragment((DeferredFragment) event.getComponent()); + } + + /** + * + */ + private void processDeferredFragment(DeferredFragment comp) { + // Find the "place-holder" component... + String key = ":" + comp.getPlaceHolderId(); + UIComponent placeHolder = comp.findComponent(key); + if (placeHolder != null) { + // This "should" always be the case... swap it back. + List peers = placeHolder.getParent().getChildren(); + int index = peers.indexOf(placeHolder); + peers.set(index, comp); + } + + // Queue it up... + synchronized (renderQueue) { + renderQueue.add(comp); + renderQueue.notifyAll(); + } + } + + + /** + *

    A count of remaining fragments to render.

    + */ + private transient int fragsToRender = 1; + + private transient List fragments = + new ArrayList(); + + private transient Queue renderQueue = new ConcurrentLinkedQueue(); + + /** + *

    The component family.

    + */ + public static final String FAMILY = FragmentRenderer.class.getName(); +} diff --git a/jsft/src/main/java/com/sun/jsft/event/Command.java b/jsft/src/main/java/com/sun/jsft/event/Command.java new file mode 100644 index 0000000..915b3c9 --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/event/Command.java @@ -0,0 +1,154 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +package com.sun.jsft.event; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +import javax.faces.event.AbortProcessingException; + + +/** + *

    This class represents a Command.

    + * + * Created March 31, 2011 + * @author Ken Paulsen kenapaulsen@gmail.com + */ +public abstract class Command implements Serializable { + + /** + *

    Default constructor needed for serialization.

    + */ + public Command() { + } + + /** + *

    Constructor which sets the child commands.

    + */ + public Command(List children, Command elseCommand) { + setChildCommands(children); + setElseCommand(elseCommand); + } + + /** + *

    This is the method responsible for performing the action. It is + * also responsible for invoking any of its child commands.

    + */ + public abstract Object invoke() throws AbortProcessingException; + + /** + *

    This getter method retrieves the command to be invoked if this + * command has an "else" clause. In most cases this will return + * null.

    + */ + public Command getElseCommand() { + return this.elseCommand; + } + + /** + *

    Returns a reference to list of child commands. Note, there is + * nothing to stop you from modifying this list... however, it is + * strongly discouraged and may lead to problems.

    + */ + public List getChildCommands() { + return childCommands; + } + + /** + *

    This method is a useful helper utility for invoking the child + * {@link Command}s.

    + */ + public void invokeChildCommands() { + if (this.childCommands != null) { + for (Command childCommand : this.childCommands) { + childCommand.invoke(); + } + } + } + + /** + *

    Print out the ELCommand.

    + */ + @Override + public String toString() { + StringBuilder buf = new StringBuilder(""); + if (childCommands != null) { + buf.append("{\n"); + Iterator it = childCommands.iterator(); + while (it.hasNext()) { + buf.append(it.next().toString()); + } + buf.append("}\n"); + } else { + buf.append(";\n"); + } + return buf.toString(); + } + + /** + * + */ + private void setChildCommands(List commands) { + this.childCommands = commands; + } + + /** + *

    This setter method stores the command to be invoked if this + * command has an "else" clause.

    + */ + private void setElseCommand(Command command) { + this.elseCommand = command; + } + + + /** + *

    This is the request scoped key which will store the child + * {@link Command} for the currently executing {@link Command}.

    + */ + public static final String COMMAND_KEY = "jsftCommand"; + + private static final long serialVersionUID = 6945415932011238909L; + + private List childCommands = null; + private Command elseCommand = null; +} diff --git a/jsft/src/main/java/com/sun/jsft/event/CommandEventListener.java b/jsft/src/main/java/com/sun/jsft/event/CommandEventListener.java new file mode 100644 index 0000000..7f7a019 --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/event/CommandEventListener.java @@ -0,0 +1,140 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +package com.sun.jsft.event; + +import java.util.List; +import javax.faces.context.FacesContext; +import javax.faces.event.AbortProcessingException; +import javax.faces.event.ComponentSystemEvent; +import javax.faces.event.ComponentSystemEventListener; + + +/** + *

    This class handles the dispatching of events to commands. Currently + * Commands delegate execution to EL. In the future, other Command types + * may be supported.

    + * + * Created March 29, 2011 + * @author Ken Paulsen (kenapaulsen@gmail.com) + */ +public class CommandEventListener extends Command implements ComponentSystemEventListener { + + /** + *

    Default constructor needed for serialization.

    + */ + public CommandEventListener() { + } + + /** + *

    Primary constructor used. It is neeeded in order to supply a list + * of commands.

    + */ + public CommandEventListener(List commands) { + super(commands, null); + } + + /** + *

    This method is responsible for dispatching the event to the various + * EL expressions that are listening to this event. It also stores + * the Event object in request scope under the key "theEvent" so that + * it can be accessed easiliy via EL. For example: + * util.println(theEvent);

    + */ + public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { + + // Store the event under the key "theEvent" in case we want to access + // it for some reason. + FacesContext.getCurrentInstance().getExternalContext().getRequestMap(). + put("theEvent", event); + + // Execute the child commands + invoke(); + } + + /** + *

    This is the method responsible for performing the action. It is + * also responsible for invoking any of its child commands.

    + */ + public Object invoke() throws AbortProcessingException { + // Invoke the child commands... + invokeChildCommands(); + + return null; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || (getClass() != obj.getClass())) { + return false; + } + + CommandEventListener that = (CommandEventListener) obj; + + if (hashCode() != that.hashCode()) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + if (hash == -1) { + StringBuilder builder = new StringBuilder(""); + List commands = getChildCommands(); + if (commands != null) { + for (Command command : commands) { + builder.append(command.toString()); + } + } + hash = builder.toString().hashCode(); + } + return hash; + } + + + private transient int hash = -1; + private static final long serialVersionUID = 6945415935164238909L; +} diff --git a/jsft/src/main/java/com/sun/jsft/event/ELCommand.java b/jsft/src/main/java/com/sun/jsft/event/ELCommand.java new file mode 100644 index 0000000..3ded561 --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/event/ELCommand.java @@ -0,0 +1,169 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +package com.sun.jsft.event; + +import com.sun.jsft.util.Util; + +import java.util.List; +import javax.el.ELContext; +import javax.el.ExpressionFactory; +import javax.el.ValueExpression; +import javax.faces.context.FacesContext; +import javax.faces.event.AbortProcessingException; + + +/** + *

    This class represents a Command that is processed via Unified EL.

    + * + * Created March 31, 2011 + * @author Ken Paulsen (kenapaulsen@gmail.com) + */ +public class ELCommand extends Command { + + /** + *

    Default constructor needed for serialization.

    + */ + public ELCommand() { + } + + /** + *

    This constructor should be used to create a new + * ELCommand instance. It expects to be passed an + * expression, and optionally a List<Command> that represent + * child commands.

    + * + * FIXME: Add more documentation on how this works... + */ + public ELCommand(String resultVar, String el, List childCommands, Command elseCommand) { + super(childCommands, elseCommand); + this.resultVar = resultVar; + this.el = el; + } + + /** + *

    This method is responsible for dispatching the event to the various + * EL expressions that are listening to this event. It also stores + * the Event object in request scope under the key "theEvent" so that + * it can be accessed easiliy via EL. For example: + * util.println(theEvent);

    + */ + public Object invoke() throws AbortProcessingException { + FacesContext ctx = FacesContext.getCurrentInstance(); + ELContext elCtx = ctx.getELContext(); + + // Store the Command for access inside the expression. + // This is useful for loops or other commands which need access to + // their child Commands. + ctx.getExternalContext().getRequestMap().put(COMMAND_KEY, this); + + // Create expression + ExpressionFactory fact = ctx.getApplication().getExpressionFactory(); + ValueExpression ve = null; + Object result = null; + if (this.el.length() > 0) { + ve = fact.createValueExpression( + elCtx, "#{" + this.el + "}", Object.class); + // Execute expression + result = ve.getValue(elCtx); + + // If we should store the result... do it. + if (this.resultVar != null) { + ve = fact.createValueExpression( + elCtx, "#{" + this.resultVar + "}", Object.class); + ve.setValue(elCtx, result); + } + } else { + // Do this since we have no command to execute (which is normally + // responsible for doing this) + invokeChildCommands(); + } + return result; + } + + /** + *

    Print out the ELCommand.

    + */ + @Override + public String toString() { + StringBuilder buf = new StringBuilder(el); + buf.append(super.toString()); + return buf.toString(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || (getClass() != obj.getClass())) { + return false; + } + + ELCommand that = (ELCommand) obj; + + if (hashCode() == that.hashCode()) { + return true; + } + + return false; + } + + @Override + public int hashCode() { + if (hash == -1) { + StringBuilder builder = new StringBuilder(el); + List children = getChildCommands(); + if (children != null) { + for (Command command : children) { + builder.append(command.toString()); + } + } + hash = builder.toString().hashCode(); + } + return hash; + } + + private String resultVar = null; + private String el = null; + private transient int hash = -1; + private static final long serialVersionUID = 6201115935174238909L; +} diff --git a/jsft/src/main/java/com/sun/jsft/facelets/CommandParser.java b/jsft/src/main/java/com/sun/jsft/facelets/CommandParser.java new file mode 100644 index 0000000..ccc5c02 --- /dev/null +++ b/jsft/src/main/java/com/sun/jsft/facelets/CommandParser.java @@ -0,0 +1,482 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Portions Copyright (c) 2011 Ken Paulsen + * + * 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.dev.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. + */ + +package com.sun.jsft.facelets; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Stack; + +import com.sun.jsft.util.LogUtil; + + +/** + *

    This class is responsible for the actual parsing of a template.

    + * + *

    This class is intended to read the template one time. Often it may be + * useful to cache the result as it would be inefficient to reread a + * template multiple times. Templates that are generated from this class + * are intended to be static and safe to share. However, this class + * itself is not thread safe.

    + * + * @author Ken Paulsen (kenapaulsen@gmail.com) + */ +public class CommandParser { + + /** + *

    Constructor which accepts a InputStream.

    + * + * @param stream InputStream for the template. + */ + public CommandParser(InputStream stream) { + _inputStream = stream; + } + + /** + *

    Accessor for the InputStream. This comes from + * the supplied InputStream.

    + */ + public InputStream getInputStream() throws IOException { + return _inputStream; + } + + /** + *

    Creates the Reader Object.

    + * + * @throws IOException + */ + public void open() throws IOException { + if (_reader != null) { + // Generally this should not happen, but just in case... start over + close(); + } + +// FIXME: It is possible while evaluating the file an #include may need to log a message to the screen! Provide a callback mechanism to do this in a Template-specific way + // Create the reader from the stream + _reader = new BufferedReader( + new InputStreamReader( + new BufferedInputStream(getInputStream()))); + + // Initialize the queue we will use to push values back + _stack = new Stack(); + } + + /** + *

    This method closes the stream if it is open. It doesn't throw an + * exception, instead it logs any exceptions at the CONFIG level.

    + */ + public void close() { + try { + if (_reader != null) { + _reader.close(); + } + } catch (Exception ex) { + if (LogUtil.configEnabled(this)) { + LogUtil.config("Exception while closing stream.", ex); + } + } + } + + /** + *

    This method returns the next character.

    + */ + public int nextChar() throws IOException { + if (!_stack.empty()) { + // We have values in the queue + return _stack.pop().charValue(); + } + return _reader.read(); + } + + /** + *

    This method pushes a character on the read queue so that it will + * be read next.

    + */ + public void unread(int ch) { + _stack.push(new Character((char) ch)); + } + + /** + *

    This method returns a String of characters from the + * current position in the file until the given character (or end of + * file) is encountered. It will leave the given character in the + * buffer, so the next character to be read will be the + * endingChar or -1.

    + * + * @param endingChar The character to read up to, but not including + * @param skipComments true to strip comments. + */ + public String readUntil(int endingChar, boolean skipComments) throws IOException { + return readUntil(new int[] {endingChar}, skipComments); + } + + /** + * + */ + public String readUntil(int[] endingChars, boolean skipComments) throws IOException { + if (skipComments) { + // In case we start on a comment and should skip it... + skipCommentsAndWhiteSpace(""); + } + int tmpch; + int next = nextChar(); + StringBuffer buf = new StringBuffer(); + while (!isInArray(endingChars, next) && (next != -1)) { + switch (next) { + case '\'' : + case '\"' : + if (skipComments) { + // In this case, we want to make sure no comments are + // skipped when inside a quote + // + // NOTE: Also means endingChars will not be found in + // a quote. + buf.append((char) next); + buf.append(readUntil(next, false)); + buf.append((char) next); + nextChar(); // Throw away the last char read... + } else { + buf.append((char) next); + } + break; + case '#' : + case '/' : + case '<' : + // When reading we want to ignore comments, don't skip + // whitespace, though... + if (skipComments) { + unread(next); + skipCommentsAndWhiteSpace(""); + // If same char, read next to prevent infinite loop + // We don't have to go through switch again b/c its + // not the ending char and its not escaped -- so it is + // safe to add. + tmpch = nextChar(); + if (next == tmpch) { + buf.append((char) next); + } else { + // We're somewhere different, unread + unread(tmpch); + } + } else { + buf.append((char) next); + } + break; + case '\\' : + // Escape Character... + next = nextChar(); + if (next == 'n') { + // Special case, insert a '\n' character. + buf.append('\n'); + } else if (next == 't') { + // Special case, insert a '\t' character. + buf.append('\t'); + } else if (next != '\n') { + // add the next char unless it's a return char + buf.append((char) next); + } + break; + default: + buf.append((char) next); + break; + } + next = nextChar(); + } + if (next != -1) { + unread(next); + } + + // Return the result + return buf.toString(); + } + + /** + *

    This method returns a String of characters from the + * current position in the file until the given String (or end of + * file) is encountered. It will not leave the given String in the + * buffer, so the next character to be read will be the character + * following the given character.

    + * + * @param endingStr The terminating String. + * @param skipComments true to ignore comments. + */ + public String readUntil(String endingStr, boolean skipComments) throws IOException { + // Sanity Check + if ((endingStr == null) || (endingStr.length() == 0)) { + return ""; + } + + // Break String into characters + char arr[] = endingStr.toCharArray(); + int arrlen = arr.length; + + StringBuffer buf = new StringBuffer(""); + int ch = nextChar(); // Read a char to unread + int idx = 1; + do { + // We didn't find the end, push read values back on queue + unread(ch); + for (int cnt = idx-1; cnt > 0; cnt--) { + unread(arr[cnt]); + } + + // Read until the beginning of the end (maybe) + buf.append(readUntil(arr[0], skipComments)); + //buf.append(arr[0]); // readUntil reads but doesn't return this char + + // Check to see if we are at the end + for (idx = 1; idx < arrlen; idx++) { + ch = nextChar(); + if (ch != arr[idx]) { + // This is not the end! + break; + } + } + } while ((ch != -1) && (idx < arrlen)); + + // Append the remaining characters (use idx in case we hit eof)... + for (int cnt = 1; cnt < idx; cnt++) { + buf.append(arr[cnt]); + } + + if (arrlen != idx) { + // Didn't find it! + throw new IllegalStateException("Unable to find: '" + endingStr + + "'. Read to EOF and gave up. Read: \n" + buf.toString()); + } + + // Return the result + return buf.toString(); + } + + /** + *

    This method skips the given String of characters (usually used to + * skip white space. The contents of the String that is skipped is + * lost. Often you may wish to skip comments as well, use + * {@link CommandParser#skipCommentsAndWhiteSpace(String)} in this + * case.

    + * + * @param skipChars The white space characters to skip. + * + * @see CommandParser#skipCommentsAndWhiteSpace(String) + */ + public void skipWhiteSpace(String skipChars) throws IOException { + int next = nextChar(); + while ((next != -1) && (skipChars.indexOf(next) != -1)) { + // Skip... + next = nextChar(); + } + + // This will skip one too many + unread(next); + } + + /** + *

    Normally you don't just want to skip white space, you also want to + * skip comments. This method allows you to do that. It skips + * comments of the following types:

    + * + * + *
    • // - Comment extends to the rest of the line.
    • + *
    • # - Comment extends to the rest of the line.
    • + *
    • /* - Comment extends until closing '*' and '/'.
    • + *
    • <!-- - Comment extends until closing -->.
    + *
    + * + * @param skipChars The white space characters to skip + * + * @see CommandParser#skipWhiteSpace(String) + */ + public void skipCommentsAndWhiteSpace(String skipChars) throws IOException { + int ch = 0; + while (ch != -1) { + ch = nextChar(); + switch (ch) { + case '#' : + // Skip rest of line + readLine(); + break; + case '/' : + ch = nextChar(); + if (ch == '/') { + // Skip rest of line + readLine(); + } else if (ch == '*') { + // Throw away everything until '*' & '/'. + readUntil("*/", false); + nextChar(); // Throw away the last char read... + } else { + // Not a comment, don't read + unread(ch); + unread('/'); + ch = -1; // Exit loop + } + break; + case '<' : + ch = nextChar(); // ! + if (ch == '!') { + ch = nextChar(); // - + if (ch == '-') { + ch = nextChar(); // - + if (ch == '-') { + // Ignore HTML-style comment + readUntil("-->", false); + nextChar(); // Throw away the last char read... + } else { + // Not a comment, probably a mistake... lets + // throw an exception + unread(ch); + unread('-'); + unread('!'); + unread('<'); + throw new IllegalArgumentException("Invalid " + + "comment! Expected comment to begin " + + "with \" + + + + + + http://jsftemplating.java.net/jsft + + + event + com.sun.jsft.facelets.EventHandler + + Name of the event for which to install a listener. The + following table lists the valid values for this attribute, + and the corresponding event type for which the listener + action is registered.

    + + + + + + + + + + + + +
    value for "type" tag attributeType of event sent to listener method
    preRenderComponentjavax.faces.event.PreRenderComponentEvent
    postAddToViewjavax.faces.event.PostAddToViewEvent
    preValidatejavax.faces.event.PreValidateEvent
    postValidatejavax.faces.event.PostValidateEvent
    + +

    In addition to these values, the fully qualified class + name of any java class that extends + javax.faces.event.ComponentSystemEvent may be + used as the value of the "type" attribute.

    + +

    The listener that is registered will dipatch to the + expressions specified in the body of this element. Each + expression must be separated by a semicolon and need not + be enclosed in #{}.

    + ]]>
    + type + true + java.lang.String +
    +
    + + + deferredFragment + + com.sun.jsft.component.fragment.DeferredFragment + + + +
    diff --git a/jsftemplating-dt/pom.xml b/jsftemplating-dt/pom.xml new file mode 100644 index 0000000..50f1c1f --- /dev/null +++ b/jsftemplating-dt/pom.xml @@ -0,0 +1,77 @@ + + + + + 4.0.0 + + com.sun.jsftemplating + jsftemplating-parent + 2.1.1-SNAPSHOT + + jsftemplating-dt + + + + + org.apache.maven.plugins + maven-compiler-plugin + + none + + + + org.apache.felix + maven-bundle-plugin + + + bundle-manifest + process-classes + + manifest + + + + + + + diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/FormatDefinition.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/FormatDefinition.java new file mode 100644 index 0000000..f4b3576 --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/FormatDefinition.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + *

    This is the FormatDefinition Annotation. It is + * expected to exist on each + * {@link com.sun.jsftemplating.component.factory.ComponentFactory}. + * It must specify an identifier for the ComponentFactory + * so that it may be referenced when defining UIComponents + * in your template or code.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface FormatDefinition { +} diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/FormatDefinitionAP.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/FormatDefinitionAP.java new file mode 100644 index 0000000..3191568 --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/FormatDefinitionAP.java @@ -0,0 +1,129 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007-2014 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.util.Enumeration; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +/** + * A JSR 169 compliant annotation processor for FormatDefinition annotation + * This is required for JDK8+, since APT has been deprecated. + * @author Romain Grecourt + */ +@SupportedAnnotationTypes(value = {"com.sun.jsftemplating.annotation.FormatDefinition"}) +@SupportedSourceVersion(SourceVersion.RELEASE_6) +public class FormatDefinitionAP extends AbstractProcessor { + + public static final String FACTORY_FILE = "META-INF/jsftemplating/FormatDefinition.map"; + private PrintWriter writer = null; + private boolean _setup = false; + + private boolean setup() { + if (_setup) { + // Don't do setup more than once + return true; + } + try { + // Create factory mapping file + writer = getMapWriter(); + } catch (IOException ex) { + StringWriter buf = new StringWriter(); + ex.printStackTrace(new PrintWriter(buf)); + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + String.format("Unable to write %s file while processing @FormatDefinition annotation %s", + FACTORY_FILE, + buf.toString())); + return false; + } + _setup = true; + return _setup; + } + + private PrintWriter getMapWriter() throws IOException { + PrintWriter _writer = null; + ClassLoader cl = this.getClass().getClassLoader(); + URL url; + for (Enumeration urls = cl.getResources(FACTORY_FILE); + urls.hasMoreElements() && (_writer == null);) { + url = urls.nextElement(); + if ((url != null) && new File(url.getFile()).canRead()) { + // Append to the existing file... + _writer = new PrintWriter(new FileOutputStream(url.getFile(), true)); + } + } + if (_writer == null) { + // File not found, create a new one... + FileObject fo = processingEnv.getFiler().createResource( + StandardLocation.CLASS_OUTPUT, + "", + FACTORY_FILE); + _writer = new PrintWriter(fo.openWriter()); + return _writer; + } + return _writer; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_6) > 0) { + return SourceVersion.valueOf("RELEASE_7"); + } else { + return SourceVersion.RELEASE_6; + } + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + + setup(); + + for (Element decl : roundEnv.getElementsAnnotatedWith(FormatDefinition.class)) { + for (AnnotationMirror an : decl.getAnnotationMirrors()) { + writer.println(decl.toString()); + } + } + + if(_setup){ + writer.close(); + } + return roundEnv.processingOver(); + } +} diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/Handler.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/Handler.java new file mode 100644 index 0000000..1c8fd4a --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/Handler.java @@ -0,0 +1,51 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + *

    This is the Handler Annotation. It is + * expected to exist on each + * {@link com.sun.jsftemplating.component.factory.ComponentFactory}. + * It must specify an identifier for the ComponentFactory + * so that it may be referenced when defining UIComponents + * in your template or code.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface Handler { + public String id(); + public HandlerInput[] input() default {}; + public HandlerOutput[] output() default {}; + + public static final String ID = "id"; + public static final String INPUT = "input"; + public static final String OUTPUT = "output"; +} diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerAP.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerAP.java new file mode 100644 index 0000000..0c459b2 --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerAP.java @@ -0,0 +1,396 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006-2014 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedOptions; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.util.SimpleElementVisitor6; +import javax.tools.Diagnostic; +import javax.tools.Diagnostic.Kind; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +/** + * A JSR 169 compliant annotation processor for Handler annotation + * This is required for JDK8+, since APT has been deprecated. + * @author Romain Grecourt + */ +@SupportedAnnotationTypes(value = { + "com.sun.jsftemplating.annotation.Handler", + "com.sun.jsftemplating.annotation.HandlerInput", + "com.sun.jsftemplating.annotation.HandlerOutput"}) +@SupportedSourceVersion(SourceVersion.RELEASE_6) +@SupportedOptions(value = { + "AnnotationVerifier.Annotations", + "AnnotationVerifier.Baseclasses", + "AnnotationVerifier.ClassAnnotation.Mappings"}) +public class HandlerAP extends AbstractProcessor { + +// public static final String HANDLER_FILE = "Handler.map"; + public static final String HANDLER_FILE = "META-INF/jsftemplating/Handler.map"; + private PrintWriter writer = null; + private boolean _setup = false; + private Map handlers = new HashMap(); + + private boolean setup() { + if (_setup) { + // Don't do setup more than once + return true; + } + try { + // Create factory mapping file + writer = getMapWriter(); + } catch (IOException ex) { + StringWriter buf = new StringWriter(); + ex.printStackTrace(new PrintWriter(buf)); + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + String.format("Unable to write %s file while processing @FormatDefinition annotation %s", + HANDLER_FILE, + buf.toString())); + return false; + } + _setup = true; + return _setup; + } + + private PrintWriter getMapWriter() throws IOException { + PrintWriter _writer = null; + ClassLoader cl = this.getClass().getClassLoader(); + URL url; + for (Enumeration urls = cl.getResources(HANDLER_FILE); + urls.hasMoreElements() && (_writer == null);) { + url = urls.nextElement(); + if ((url != null) && new File(url.getFile()).canRead()) { + // Append to the existing file... + _writer = new PrintWriter(new FileOutputStream(url.getFile(), true)); + } + } + if (_writer == null) { + // File not found, create a new one... + FileObject fo = processingEnv.getFiler().createResource( + StandardLocation.CLASS_OUTPUT, + "", + HANDLER_FILE); + _writer = new PrintWriter(fo.openWriter()); + return _writer; + } + return _writer; + } + + private static final class ElementVisitor extends SimpleElementVisitor6 { + + @Override + public TypeElement visitType(TypeElement e, Void p) { + return e; + } + } + + private static final class ExecutableElementVisitor extends SimpleElementVisitor6 { + + @Override + public ExecutableElement visitExecutable(ExecutableElement e, Void p) { + return e; + } + } + + private static TypeElement getTypeElement(Element elt) { + return elt.accept(new ElementVisitor(), null); + } + + private static TypeElement getDeclaringTypeElement(Element elt) { + return getTypeElement(elt.getEnclosingElement()); + } + + private String getJavadocComments(Element elt) { + return processingEnv.getElementUtils().getDocComment(elt); + } + + /** + *

    + * This is a helper method that writes out property lines to represent + * either a HandlerInput or a HandlerOutput. The type + * that is passed in is expected to be either input or + * output.

    + */ + private void writeIOProperties(String id, String type, List ioList) { + int cnt = 0; + for (AnnotationValue ioVal : ioList) { + // Process each @HandlerInput annotation... + for (Map.Entry prop + : ((AnnotationMirror) ioVal.getValue()).getElementValues().entrySet()) { + // Look at each "param": @Handlerput(param=) + writer.println(id + "." + type + "[" + cnt + "]." + + prop.getKey().getSimpleName() + "=" + + convertClassName(prop.getValue().getValue().toString())); + } + cnt++; + } + } + + /** + *

    + * This method attempts to convert the given clsName to + * a valid class name. The issue is that arrays appear something like + * "java.lang.String[]" where they should appear + * "[Ljava.lang.String;".

    + */ + private String convertClassName(String str) { + int idx = str.indexOf("[]"); + if (idx == -1) { + // For not only worry about Strings that contain array brackets + return str; + } + + // Count []'s + int count = 0; + while (idx != -1) { + str = str.replaceFirst("\\[]", ""); + idx = str.indexOf("[]"); + count++; + } + + // Generate new String + String brackets = ""; + for (idx = 0; idx < count; idx++) { + brackets += "["; + } + // Return something of the format: [Ljava.lang.String; + return brackets + "L" + str + ";"; + } + + /** + *

    + * This method strips off HTML tags, converts "<" and ">", + * inserts '#' characters in front of each line, and ensures there + * are no trailing returns.

    + */ + private String formatComment(String javadoc) { + if (javadoc == null) { + // No JavaDoc, return + return ""; + } + + // First trim off extra stuff + int idx = javadoc.indexOf("@param"); + if (idx > -1) { + // Ignore @param stuff + javadoc = javadoc.substring(0, idx); + } + javadoc = javadoc.trim(); + + // Now process the String + StringBuilder buf = new StringBuilder("\n# "); + int len = javadoc.length(); + char ch; + idx = 0; + while (idx < len) { + ch = javadoc.charAt(idx); + switch (ch) { + case '&': + if ((idx + 3) < len) { + if ((javadoc.charAt(idx + 2) == 't') + && (javadoc.charAt(idx + 3) == ';')) { + if (javadoc.charAt(idx + 1) == 'g') { + buf.append('>'); + idx += 3; + } else if (javadoc.charAt(idx + 1) == 'l') { + buf.append('<'); + idx += 3; + } + } + } + break; + case '<': + idx++; + while ((idx < len) && (javadoc.charAt(idx) != '>')) { + idx++; + } + break; + case '>': + idx++; + while ((idx < len) && (javadoc.charAt(idx) != '<')) { + idx++; + } + break; + case '\n': + case '\r': + if (((idx + 1) > len) + && ((javadoc.charAt(idx + 1) == '\n') + || (javadoc.charAt(idx + 1) == '\r'))) { + idx++; + } + buf.append("\n# "); + break; + default: + buf.append(ch); + } + idx++; + } + + // Return the stripped javadoc + return buf.toString(); + } + + @Override + public SourceVersion getSupportedSourceVersion() { + if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_6) > 0) { + return SourceVersion.valueOf("RELEASE_7"); + } else { + return SourceVersion.RELEASE_6; + } + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + String key; + Object value; + String id; + List input; + List output; + + setup(); + + for (Element decl : roundEnv.getElementsAnnotatedWith(Handler.class)) { + for (AnnotationMirror an : decl.getAnnotationMirrors()) { + // Loop through the NVPs contained in the annotation + id = null; + input = null; + output = null; + for (Map.Entry entry + : an.getElementValues().entrySet()) { + // At this point I'm processing a "Handler" annotation + // it may contain "id", "input", "output" + key = entry.getKey().getSimpleName().toString(); + value = entry.getValue().getValue(); + if (key.equals(Handler.ID)) { + // Found 'id', save it + id = value.toString(); + } else if (key.equals(Handler.INPUT)) { + // Found inputs + input = (List) value; + } else if (key.equals(Handler.OUTPUT)) { + // Found outputs + output = (List) value; + } + } + + TypeElement te = getTypeElement(decl); + TypeElement teDecl = getDeclaringTypeElement(decl); + + // Sanity Check + if (id == null) { + processingEnv.getMessager().printMessage( + Kind.ERROR, + String.format("'id' is not specified for annotation of method: %s.%s", + te.getQualifiedName().toString(), + te.getSimpleName().toString()), + decl); + } + + // Check for duplicate handler definitions + if (handlers.get(id) != null) { + processingEnv.getMessager().printMessage(Kind.WARNING, + String.format( + "Handler with 'id' of '%s' is declared more than once!'", + id), + decl); + } + handlers.put(id, id); + + // Record class / method names (and javadoc comment) + writer.println(formatComment(getJavadocComments(decl))); + writer.println(String.format("%s.class=%s", id, teDecl.getQualifiedName())); + writer.println(String.format("%s.method=%s",id,decl.getSimpleName())); + + // Now record inputs for this handler... + if (input != null) { + writeIOProperties(id, "input", input); + } + + // Now record outputs for this handler... + if (output != null) { + writeIOProperties(id, "output", output); + } + + // Method signature checks... + // Make sure method is accessible (public) + if (!decl.getModifiers().contains(Modifier.PUBLIC)) { + processingEnv.getMessager().printMessage(Kind.ERROR, + String.format("Annotated method: %s.%s should be declared public", + teDecl.getQualifiedName().toString(), + decl.getSimpleName().toString()), + decl); + } + + // Make sure correct args are specified + ExecutableElement exe = decl.accept(new ExecutableElementVisitor(), null); + List params = exe.getParameters(); + String pdec = params.iterator().next().asType().toString(); + if ((params.size() != 1) + || !pdec.equals("com.sun.jsftemplating.layout.descriptors.handler.HandlerContext")) { + + processingEnv.getMessager().printMessage(Kind.ERROR, + String.format("Annotated method: %s.%s must contain a single parameter of type 'com.sun.jsftemplating.layout.descriptors.handler.HandlerContext', instead type: %s was found", + teDecl.getQualifiedName(), + decl.getSimpleName(), + pdec), + decl); + } + +// FIXME: Consider an alternate method declaration that annotates a pojo method +// @Handler(id="foo") +// public String method(String a, String b, String c) +// annotates a handler "foo" with 3 inputs (a:String, b:String, c:String) and 1 output "result:String" +// Will need a special way to invoke this. + } + } + + if(_setup){ + writer.close(); + } + return roundEnv.processingOver(); + } +} diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerInput.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerInput.java new file mode 100644 index 0000000..2ae737d --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerInput.java @@ -0,0 +1,59 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + *

    This is the HandlerInput Annotation. It is + * expected to exist on each + * {@link com.sun.jsftemplating.component.factory.ComponentFactory}. + * It must specify an identifier for the ComponentFactory + * so that it may be referenced when defining UIComponents + * in your template or code.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface HandlerInput { + + public String name(); + public Class type() default Object.class; + public boolean required() default DEFAULT_REQUIRED; + // Annotations don't allow Object, use String + // Annotations don't allow null, use special String + public String defaultValue() default DEFAULT_DEFAULT_VALUE; + + public static final String NAME = "name"; + public static final String DEFAULT = "defaultValue"; + public static final String TYPE = "type"; + public static final String REQUIRED = "required"; + + public static final boolean DEFAULT_REQUIRED = false; + public static final String DEFAULT_DEFAULT_VALUE = "jsfTempNULLString"; +} diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerOutput.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerOutput.java new file mode 100644 index 0000000..64bfde3 --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/HandlerOutput.java @@ -0,0 +1,49 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + *

    This is the HandlerOutput Annotation. It is + * expected to exist on each + * {@link com.sun.jsftemplating.component.factory.ComponentFactory}. + * It must specify an identifier for the ComponentFactory + * so that it may be referenced when defining UIComponents + * in your template or code.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface HandlerOutput { + public String name(); + public Class type() default Object.class; + + public static final String NAME = "name"; + public static final String TYPE = "type"; +} diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/UIComponentFactory.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/UIComponentFactory.java new file mode 100644 index 0000000..77190e5 --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/UIComponentFactory.java @@ -0,0 +1,47 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + *

    This is the UIComponentFactory Annotation. It is + * expected to exist on each + * {@link com.sun.jsftemplating.component.factory.ComponentFactory}. + * It must specify an identifier for the ComponentFactory + * so that it may be referenced when defining UIComponents + * in your template or code.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface UIComponentFactory { + public String value(); + + public static final String FACTORY_ID = "value"; +} diff --git a/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/UIComponentFactoryAP.java b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/UIComponentFactoryAP.java new file mode 100644 index 0000000..082abaa --- /dev/null +++ b/jsftemplating-dt/src/main/java/com/sun/jsftemplating/annotation/UIComponentFactoryAP.java @@ -0,0 +1,156 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006-2014 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.annotation; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.util.Enumeration; +import java.util.Map; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedSourceVersion; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic.Kind; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +/** + * A JSR 169 compliant annotation processor for UIComponentFactory annotation + * This is required for JDK8+, since APT has been deprecated. + * @author Romain Grecourt + */ +@SupportedAnnotationTypes(value = {"com.sun.jsftemplating.annotation.UIComponentFactory"}) +@SupportedSourceVersion(SourceVersion.RELEASE_6) +public class UIComponentFactoryAP extends AbstractProcessor { + + public static final String FACTORY_FILE = "META-INF/jsftemplating/UIComponentFactory.map"; + private boolean _setup = false; + private PrintWriter writer = null; + + private boolean setup() { + if (_setup) { + // Don't do setup more than once + return true; + } + try { + // Create factory mapping file + writer = getMapWriter(); + } catch (IOException ex) { + StringWriter buf = new StringWriter(); + ex.printStackTrace(new PrintWriter(buf)); + processingEnv.getMessager().printMessage( + Kind.ERROR, + String.format("Unable to write %s file while processing @UIComponentFactory annotation %s", + FACTORY_FILE, + buf.toString())); + return false; + } + _setup = true; + return _setup; + } + + private PrintWriter getMapWriter() throws IOException { + PrintWriter _writer = null; + ClassLoader cl = this.getClass().getClassLoader(); + URL url; + for (Enumeration urls = cl.getResources(FACTORY_FILE); + urls.hasMoreElements() && (_writer == null);) { + url = urls.nextElement(); + if ((url != null) && new File(url.getFile()).canRead()) { + // Append to the existing file... + _writer = new PrintWriter(new FileOutputStream(url.getFile(), true)); + } + } + if (_writer == null) { + // File not found, create a new one... + FileObject fo = processingEnv.getFiler().createResource( + StandardLocation.CLASS_OUTPUT, + "", + FACTORY_FILE); + _writer = new PrintWriter(fo.openWriter()); + return _writer; + } + return _writer; + } + + private static String escape(String str) { + if (str == null) { + return ""; + } + StringBuilder buf = new StringBuilder(""); + for (char ch : str.trim().toCharArray()) { + switch (ch) { + case ':': + case '=': + buf.append('\\').append(ch); + break; + default: + buf.append(ch); + } + } + return buf.toString(); + } + + @Override + public SourceVersion getSupportedSourceVersion() { + if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_6) > 0) { + return SourceVersion.valueOf("RELEASE_7"); + } else { + return SourceVersion.RELEASE_6; + } + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + setup(); + for (Element decl : roundEnv.getElementsAnnotatedWith(UIComponentFactory.class)) { + for (AnnotationMirror an : decl.getAnnotationMirrors()) { + for(Map.Entry entry + : an.getElementValues().entrySet()){ + if (entry.getKey().getSimpleName().contentEquals( + UIComponentFactory.FACTORY_ID)) { + // Write NVP using the PrintWriter + writer.println( + escape(entry.getValue().getValue().toString()) + + "=" + decl.toString()); + } + } + } + } + if(_setup){ + writer.close(); + } + return roundEnv.processingOver(); + } +} diff --git a/jsftemplating-dt/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/jsftemplating-dt/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..b4c7ea5 --- /dev/null +++ b/jsftemplating-dt/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1,3 @@ +com.sun.jsftemplating.annotation.HandlerAP +com.sun.jsftemplating.annotation.FormatDefinitionAP +com.sun.jsftemplating.annotation.UIComponentFactoryAP \ No newline at end of file diff --git a/jsftemplating/faces-config.NavData b/jsftemplating/faces-config.NavData new file mode 100644 index 0000000..298bfc5 --- /dev/null +++ b/jsftemplating/faces-config.NavData @@ -0,0 +1,6 @@ + + + + + + diff --git a/jsftemplating/pom.xml b/jsftemplating/pom.xml new file mode 100644 index 0000000..84bc4a0 --- /dev/null +++ b/jsftemplating/pom.xml @@ -0,0 +1,147 @@ + + + + + 4.0.0 + + com.sun.jsftemplating + jsftemplating-parent + 2.1.1-SNAPSHOT + + jsftemplating + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + bundle-jsft + process-resources + + unpack-dependencies + + + true + jsft + ${project.build.outputDirectory} + META-INF/MANIFEST.MF + + + + + + org.apache.felix + maven-bundle-plugin + + + bundle-manifest + process-classes + + manifest + + + + com.sun.jsftemplating + javax.faces + com.sun.data.provider.*;resolution:=optional;password=GlassFish,!com.sun.jsftemplating.annotation.*,* + !com.sun.jsftemplating.annotation.*,!com.sun.data.*,com.sun.jsftemplating.*;version=${project.osgi.version} + + + + + + + + + + + javax.servlet + javax.servlet-api + + + org.glassfish + javax.faces + test + + + javax.faces + javax.faces-api + + + javax.el + el-api + + + com.sun.woodstock.dependlibs + dataprovider + + + com.sun.jsftemplating + jsft + ${project.version} + + true + + + com.sun.jsftemplating + jsftemplating-dt + ${project.version} + + + junit + junit + test + + + org.mockito + mockito-all + 1.9.5 + test + + + diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/TemplatingException.java b/jsftemplating/src/main/java/com/sun/jsftemplating/TemplatingException.java new file mode 100644 index 0000000..6319fc0 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/TemplatingException.java @@ -0,0 +1,145 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating; + +import javax.faces.component.UIComponent; + +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + *

    This is the base exception class for other exception types that may be + * used in this project. It provides a means for setting / obtaining the + * responsible {@link LayoutElement} and / or UIComponent + * associated with the Exception. This information is + * optional and may be null.

    + */ +public class TemplatingException extends RuntimeException { + private static final long serialVersionUID = 1L; + + /** + *

    This is the preferred constructor.

    + */ + public TemplatingException(String msg, Throwable ex, LayoutElement elt, UIComponent comp) { + super(msg, ex); + + // Setup the rest + setResponsibleLayoutElement(elt); + setResponsibleUIComponent(comp); + } + + /** + * + */ + public TemplatingException() { + super(); + } + + /** + * + */ + public TemplatingException(LayoutElement elt, UIComponent comp) { + super(); + + // Setup the rest + setResponsibleLayoutElement(elt); + setResponsibleUIComponent(comp); + } + + /** + * + */ + public TemplatingException(Throwable ex) { + super(ex); + } + + /** + * + */ + public TemplatingException(Throwable ex, LayoutElement elt, UIComponent comp) { + super(ex); + + // Setup the rest + setResponsibleLayoutElement(elt); + setResponsibleUIComponent(comp); + } + + /** + * + */ + public TemplatingException(String msg) { + super(msg); + } + + /** + * This is the preferred constructor if there is no root cause. + */ + public TemplatingException(String msg, LayoutElement elt, UIComponent comp) { + super(msg); + + // Setup the rest + setResponsibleLayoutElement(elt); + setResponsibleUIComponent(comp); + } + + /** + * + */ + public TemplatingException(String msg, Throwable ex) { + super(msg, ex); + } + + /** + * Allow the Exception to hold the responsible UIComponent + */ + public void setResponsibleUIComponent(UIComponent comp) { + _comp = comp; + } + + /** + * Allow the Exception to hold the responsible UIComponent + */ + public UIComponent getResponsibleUIComponent() { + return _comp; + } + + /** + * Allow the Exception to hold the responsible LayoutElement + */ + public void setResponsibleLayoutElement(LayoutElement elt) { + _elt = elt; + } + + /** + * Allow the responsible LayoutElement to be obtained. + * + * @return The responsible LayoutElement (null if not specified) + */ + public LayoutElement getResponsibleLayoutElement() { + return _elt; + } + + + private UIComponent _comp = null; + private LayoutElement _elt = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/AjaxRequest.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/AjaxRequest.java new file mode 100644 index 0000000..61d6195 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/AjaxRequest.java @@ -0,0 +1,57 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + + +/** + *

    This UIComponent exists to facilitate Ajax requests. + * Since these requests send information via the XMLHttpRequest Object, a + * standard href or form submit will not work. Further it is cumbersome + * to override the JavaScript in the available set of components to + * expect the developer to do this for each request.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class AjaxRequest extends TemplateComponentBase { + /** + *

    Constructor for AjaxRequest.

    + */ + public AjaxRequest() { + super(); + setRendererType("com.sun.jsftemplating.AjaxRequest"); + setLayoutDefinitionKey(LAYOUT_KEY); + } + + /** + *

    Return the family for this component.

    + */ + public String getFamily() { + return "com.sun.jsftemplating.AjaxRequest"; + } + + /** + *

    This is the location of the XML file that declares the layout for + * the AjaxRequest. (/jsftemplating/ajaxRequest.xml)

    + */ + public static final String LAYOUT_KEY = "/jsftemplating/ajaxRequest.xml"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/ChildManager.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/ChildManager.java new file mode 100644 index 0000000..ca4f207 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/ChildManager.java @@ -0,0 +1,55 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This interface defines a method to find or create a child + * UIComponent. It is designed to be used in conjunction + * with UIComponent implementations.

    + * + * @see TemplateComponent + * @see com.sun.jsftemplating.component.ComponentUtil + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface ChildManager { + + /** + *

    This method will find the request child UIComponent by id (the id + * is obtained from the given {@link LayoutComponent}). If it is not + * found, it will attempt to create it from the supplied + * {@link LayoutComponent}.

    + * + * @param context FacesContext + * @param descriptor {@link LayoutComponent} describing the UIComponent + * + * @return Requested UIComponent + */ + public UIComponent getChild(FacesContext context, LayoutComponent descriptor); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/ComponentUtil.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/ComponentUtil.java new file mode 100644 index 0000000..f0e5bab --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/ComponentUtil.java @@ -0,0 +1,664 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.el.ELContext; +import javax.el.ValueExpression; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.el.EvaluationException; + +import com.sun.jsftemplating.el.VariableResolver; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.util.LogUtil; +import com.sun.jsftemplating.util.TypeConverter; + + +/** + *

    Utility class that contains helper methods for components.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ComponentUtil { + + /** + *

    Default Constructor.

    + */ + private ComponentUtil() { + } + + /** + *

    Method to get access to the ComponentUtil instance for the current + * application.

    + */ + public static ComponentUtil getInstance(FacesContext ctx) { + ComponentUtil cu = null; + if (ctx != null) { + Map appMap = + ctx.getExternalContext().getApplicationMap(); + cu = (ComponentUtil) appMap.get(COMPONENT_UTIL_KEY); + if (cu == null) { + cu = new ComponentUtil(); + // Perhaps a SoftReference would be a good idea here? + appMap.put(COMPONENT_UTIL_KEY, cu); + } + } else { + // Not JSF env, create every time... + cu = new ComponentUtil(); + } + return cu; + } + + /** + *

    Return a child with the specified component id from the specified + * component. If not found, return null.

    + * + *

    This method will NOT create a new UIComponent.

    + * + * @param parent UIComponent to be searched + * @param id Component id (or facet name) to search for + * + * @return The child UIComponent if it exists, null otherwise. + */ + public UIComponent getChild(UIComponent parent, String id) { + return findChild(parent, id, id); + } + + /** + *

    Return a child with the specified component id (or facetName) from + * the specified component. If not found, return null. + * facetName or id may be null to avoid + * searching the facet Map or the parent's children.

    + * + *

    This method will NOT create a new UIComponent.

    + * + * @param parent UIComponent to be searched + * @param id id to search for + * @param facetName Facet name to search for + * + * @return The child UIComponent if it exists, null otherwise. + */ + public UIComponent findChild(UIComponent parent, String id, String facetName) { + // Sanity Check + if (parent == null) { + return null; + } + + // First search for facet + UIComponent child = null; + if (facetName != null) { + child = parent.getFacets().get(facetName); + if (child != null) { + return child; + } + } + + // Search for component by id + if (id != null) { + Iterator it = parent.getChildren().iterator(); + while (it.hasNext()) { + child = it.next(); + if (id.equals(child.getId())) { + return (child); + } + } + } + + // Not found, return null + return null; + } + + /** + *

    This method finds or creates a child UIComponent + * identified by the given id. If the child is not found, it will + * attempt to create it using the provided + * {@link com.sun.jsftemplating.component.factory.ComponentFactory} + * (factoryClass).

    + * + *

    If there are Properties to be set on the UIComponent, + * this method should generally be avoided. It is preferable to use + * the {@link #getChild(UIComponent, String, String, Properties)} + * form of getChild.

    + * + *

    + * // Example (no properties):
    + * UIComponent child = Util.getChild(component, "jklLabel", "com.sun.jsftemplating.component.factory.basic.LabelFactory");
    + * ((Label)child).setText("JKL Label:");
    + * ((Label)child).setFor("jkl");
    + *
    + * {@link LayoutComponent#encodeChild(FacesContext, UIComponent) LayoutComponent.encodeChild}(context, child); + *

    + * + * @param parent Parent UIComponent + * @param id Identifier for child UIComponent + * @param factoryClass Full {@link com.sun.jsftemplating.component.factory.ComponentFactory} class name + * + * @return The child UIComponent that was found or created. + * + * @see #getChild(UIComponent, String, String, Properties) + */ + public UIComponent getChild(UIComponent parent, String id, String factoryClass) { + return getChild(parent, id, factoryClass, id); + } + + /** + *

    Same as {@link #getChild(UIComponent, String, String)} except that + * it allows you to specify a facetName different than the id. If + * null is supplied, it won't save the component as a facet.

    + * + * @param parent Parent UIComponent + * @param id Identifier for the child UIComponent + * @param factoryClass Full {@link com.sun.jsftemplating.component.factory.ComponentFactory} class name + * @param facetName The facet name (null means don't store it) + * + * @return The child UIComponent that was found or created. + * + * @see #getChild(UIComponent, String, String) + */ + public UIComponent getChild(UIComponent parent, String id, String factoryClass, String facetName) { + return getChild(parent, id, getComponentType(factoryClass), + null, facetName); + } + + /** + *

    This method finds or creates a child UIComponent + * identified by the given id. If the child is not found, it will + * attempt to create it using the provided + * {@link com.sun.jsftemplating.component.factory.ComponentFactory} + * (factoryClass). It will also initialize the + * UIComponent using the provided set of + * Properties.

    + * + *

    + * // Example (with properties):
    + * Properties props = new Properties();
    + * props.setProperty("text", "ABC Label:");
    + * props.setProperty("for", "abc");
    + * UIComponent child = Util.getChild(component, "abcLabel", "com.sun.jsftemplating.component.factory.basic.LabelFactory", props);
    + *
    + * {@link LayoutComponent#encodeChild(FacesContext, UIComponent) LayoutComponent.encodeChild}(context, child); + *

    + * + * @param parent Parent UIComponent + * @param id Identifier for the child UIComponent + * @param factoryClass Full {@link com.sun.jsftemplating.component.factory.ComponentFactory} class name + * @param properties java.util.Properties needed to + * create and/or initialize the + * UIComponent + * + * @return The child UIComponent that was found or created. + */ + public UIComponent getChild(UIComponent parent, String id, String factoryClass, Properties properties) { + return getChild(parent, id, factoryClass, properties, id); + } + + /** + *

    Same as {@link #getChild(UIComponent, String, String, Properties)} + * except that it allows you to specify a facetName different than the + * id. If null is supplied, it won't save the component as a + * facet.

    + * + * @param parent Parent UIComponent + * @param id Identifier for the child UIComponent + * @param factoryClass Full {@link com.sun.jsftemplating.component.factory.ComponentFactory} class name + * @param properties java.util.Properties needed to + * create and/or initialize the + * UIComponent + * @param facetName The facet name (null means don't store it) + * + * @return The child UIComponent that was found or created. + */ + public UIComponent getChild(UIComponent parent, String id, String factoryClass, Properties properties, String facetName) { + return getChild(parent, id, getComponentType(factoryClass), + properties, facetName); + } + + /** + *

    This method finds or creates a child UIComponent + * identified by the given id. If the child is not found, it will + * attempt to create it using the provided {@link ComponentType} + * (type). It will also initialize the + * UIComponent using the provided set of + * properties.

    + * + * @param parent Parent UIComponent + * @param id Identifier for the child + * UIComponent + * @param type The ComponentType class name + * @param properties Properties needed to create and/or initialize + * the UIComponent + * @param facetName The facet name (null means don't store it) + * + * @return The child UIComponent that was found or created. + */ + private UIComponent getChild(UIComponent parent, String id, ComponentType type, Properties properties, String facetName) { + LayoutComponent desc = new LayoutComponent(null, id, type); + if (properties != null) { + //Remove Generics for now. Check with Ken to change thisinto HashMap. + desc.setOptions((Map) properties); + } + if (facetName != null) { + // Add the facetName to use +// FIXME: Decide if this should have its own method + desc.addOption(LayoutComponent.FACET_NAME, facetName); + } + + return getChild(parent, desc); + } + + /** + *

    This method creates a {@link ComponentType} instance from the given + * factoryClass. It will first check its cache to see if + * one has already been created. If not, it will create one and add + * to the cache for future use.

    + * + *

    This method sets factoryClass for the + * {@link ComponentType} id.

    + * + * @param facatoryClass The full classname of the + * {@link com.sun.jsftemplating.component.factory.ComponentFactory}. + * + * @return A ComponentType instance for factoryClass. + */ + private ComponentType getComponentType(String factoryClass) { + // Check the cache + ComponentType type = (ComponentType) _types.get(factoryClass); + if (type == null) { + // Not in the cache... add it... + type = new ComponentType(factoryClass, factoryClass); + Map newMap = + new HashMap(_types); + newMap.put(factoryClass, type); + _types = newMap; + } + + // Return the ComponentType + return type; + } + + /** + *

    This method finds or creates a child UIComponent + * identified by the given id. If the child is not found, it will + * attempt to create it using the provided {@link LayoutComponent} + * (descriptor). It will also initialize the + * UIComponent using the options set on the + * {@link LayoutComponent}.

    + * + *

    If parent implements {@link ChildManager}, then the + * responsibility of finding and creating the child will be delegated + * to the {@link ChildManager} UIComponent.

    + * + *

    If you are constructing and populating a LayoutComponent before + * calling this method, there are a few features that should be noted. + * Besides id and type which can be set in + * the LayoutComponent constructor, you can also set + * options, and + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler}'s.

    + * + *

    Options may be set via + * {@link LayoutComponent#setOptions(Map)}. These options will be + * applied to the UIComponent and may also be used by the + * {@link com.sun.jsftemplating.component.factory.ComponentFactory} + * while instantiating the UIComponent.

    + * + *

    {@link com.sun.jsftemplating.layout.descriptors.handler.Handler}'s + * can be supplied by calling + * {@link LayoutComponent#setHandlers(String, List)}. The + * type must match the event name which invokes the + * List of handlers you provide. The + * Renderer for this UIComponent is + * responsible for declaring and dispatching events. + * {@link com.sun.jsftemplating.renderer.TemplateRenderer} + * will invoke beforeCreate and afterCreate + * events for each child it creates (such as the one being requested + * here).

    + * + *

    + * // Example (with LayoutComponent):
    + * {@link ComponentType} type = new {@link ComponentType#ComponentType(String, String) ComponentType}("LabelFactory", "com.sun.jsftemplating.component.factory.basic.LabelFactory");
    + * {@link LayoutComponent} descriptor = new {@link LayoutComponent#LayoutComponent(LayoutElement, String, ComponentType) LayoutComponent}(null, "abcLabel", type);
    + * {@link LayoutComponent#addOption(String, Object) descriptor.addOption}("text", "ABC Label:");
    + * {@link LayoutComponent#addOption(String, Object) descriptor.addOption}("for", "abc");
    + * UIComponent child = Util.getChild(component, descriptor);
    + *
    + * {@link LayoutComponent#encodeChild(FacesContext, UIComponent) LayoutComponent.encodeChild}(context, child); + *

    + * + * @param parent Parent UIComponent + * @param descriptor The {@link LayoutComponent} describing the + * UIComponent + * + * @return The child UIComponent that was found or created. + */ + public UIComponent getChild(UIComponent parent, LayoutComponent descriptor) { + FacesContext context = FacesContext.getCurrentInstance(); + // First check to see if the UIComponent can create its own children + if (parent instanceof ChildManager) { + return ((ChildManager) parent).getChild( + context, descriptor); + } + + // Make sure it doesn't already exist + String childId = descriptor.getId(context, parent); + UIComponent childComponent = findChild(parent, childId, + (String) descriptor.getEvaluatedOption( + context, LayoutComponent.FACET_NAME, null)); + if (childComponent != null) { + return childComponent; + } + + // Not found, create a new UIComponent + return createChildComponent(context, descriptor, parent); + } + + /** + *

    This method creates a child UIComponent by using the + * provided {@link LayoutComponent} (descriptor). It + * will associate the parent and the newly created + * UIComponent.

    + * + *

    It is recommended that this method NOT be called from a Renderer. + * It should not be called if you have not yet checked to see if a + * child UIComponent with the requested ID already exists.

    + * + * @param context The FacesContext object. + * @param descriptor The {@link LayoutComponent} describing the + * UIComponent to be created. + * @param parent Parent UIComponent. + * + * @return A new UIComponent based on the provided + * {@link LayoutComponent}. + * + * @throws IllegalArgumentException Thrown if descriptor equals null. + * + * @see #getChild(UIComponent, LayoutComponent) + * @see #getChild(UIComponent, String, String, Properties) + * @see LayoutComponent#getType() + * @see ComponentType#getFactory() + * @see com.sun.jsftemplating.component.factory.ComponentFactory#create(FacesContext, LayoutComponent, UIComponent) + */ + public UIComponent createChildComponent(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Make sure a LayoutComponent was provided. + if (descriptor == null) { + throw new IllegalArgumentException("'descriptor' cannot be null!"); + } + + // Create & return the child UIComponent + return descriptor.getType().getFactory().create( + context, descriptor, parent); + } + + /** + *

    This util method will set the given key/value on the + * UIComponent. It will resolve all $...{...} + * expressions, and convert the String into a + * ValueExpression if a valid expression is detected. + * The return value will be a ValueExpression or the + * value.

    + * + * @param context FacesContext + * @param key The Property name to set + * @param value The Property value to set + * @param desc The {@link LayoutElement} associated with the + * UIComponent + * @param comp The UIComponent + * + * @return A ValueExpression, or the "$...{...}" evaulated + * value (if no ValueExpression is present). + */ + public Object setOption(FacesContext context, String key, Object value, LayoutElement desc, UIComponent comp) { + // Invoke our own EL. This is needed b/c JSF's EL is designed for + // context-insensitive EL. Resolve our variables now because we + // cannot depend on the individual components to do this later. We + // need to find a way to make this work as a regular ValueExpression... + // for now, we'll continue to use it... + value = VariableResolver.resolveVariables(context, desc, comp, value); + + // Next check to see if the value is/contains a JSF ValueExpression + if (value instanceof ValueExpression) { + if (comp != null) { + comp.setValueExpression(key, (ValueExpression) value); + } + } else if ((value instanceof String) && isValueReference((String) value)) { + ValueExpression ve = + context.getApplication().getExpressionFactory(). + createValueExpression( + context.getELContext(), (String) value, Object.class); + if (comp != null) { + comp.setValueExpression(key, ve); + } + value = ve; + } else if (comp != null) { + // In JSF, you must directly modify the attribute Map + Map attributes = comp.getAttributes(); + if (value == null) { + // Setting null, assume they want to remove the value + try { + attributes.remove(key); + } catch (Exception ex) { // Switched from IAE to E b/c of MyFaces incompatibility + // JSF is mesed up... it throws an exception if it has a + // property descriptor and you call remove(...). It also + // throws an exception if you attempt to call put w/ null + // and there is no property descriptor. Either way you + // MUST catch something and then handle the other case. + try { + attributes.put(key, (Object) null); + } catch (Exception iae) { // Switched from IAE to E b/c of MyFaces incompatibility + // We'll make this non-fatal, but log a message + if (LogUtil.infoEnabled()) { + LogUtil.info("JSFT0006", new Object[] { + key, comp.getId(), comp.getClass().getName()}); + if (LogUtil.fineEnabled()) { + LogUtil.fine("Unable to set (" + key + ").", iae); + } + } + } + } + } else { + try { + // Attempt to set the value as given... + attributes.put(key, value); + } catch (Exception ex) { // Switched from IAE to E b/c of MyFaces incompatibility + // Ok, try a little harder... + Class type = findPropertyType(comp, key); + if (type != null) { + try { + attributes.put(key, TypeConverter.asType(type, value)); + } catch (Exception ex2) { // Switched from IAE to E b/c of MyFaces incompatibility + throw new IllegalArgumentException( + "Failed to set property (" + key + ") with " + + "value (" + value + "), which is of type (" + + value.getClass().getName() + "). Expected " + + "type (" + type.getName() + "). This " + + "occured on the component named (" + + comp.getId() + ") of type (" + + comp.getClass().getName() + ").", ex2); + } + } else { + throw new IllegalArgumentException( + "Failed to set property (" + key + ") with value (" + + value + "), which is of type (" + + value.getClass().getName() + "). This occured " + + "on the component named (" + comp.getId() + + ") of type (" + comp.getClass().getName() + + ").", ex); + } + } + } + } + + // Return the value (which may be a ValueExpression) + return value; + } + + /** + *

    This method attempts to resolve the expected type for the given + * property key and UIComponent.

    + */ + private Class findPropertyType(UIComponent comp, String key) { + // First check to see if we've done this before... + Class compClass = comp.getClass(); + String cacheKey = compClass.getName() + ';' + key; + if (_typeCache.containsKey(cacheKey)) { + // May return null if method previously executed unsuccessfully + return _typeCache.get(cacheKey); + } + + // Search a little... + Class val = null; + Method meth = null; + String methodName = getGetterName(key); + try { + meth = compClass.getMethod(methodName); + } catch (NoSuchMethodException ex) { + // May fail if we have a boolean property that has an "is" getter. + try { + // Try again, replace "get" with "is" + meth = compClass.getMethod( + "is" + methodName.substring(3)); + } catch (NoSuchMethodException ex2) { + // Still not found, must not have getter / setter + ex2.printStackTrace(); + } + } + if (meth != null) { + val = meth.getReturnType(); + } else { + Object obj = comp.getAttributes().get("key"); + if (val != null) { + val = obj.getClass(); + } + } + + // Save the value for future calls for the same information + // NOTE: We do it this way to avoid modifying a shared Map + Map newTypeCache = + new HashMap(_typeCache); + newTypeCache.put(cacheKey, val); + _typeCache = newTypeCache; + + // Return the result + return val; + } + + /** + *

    This method converts the given name to a bean getter + * method name. In other words, it capitalizes the first letter and + * prepends "get".

    + */ + public String getGetterName(String name) { + return "get" + ((char) (name.charAt(0) & 0xFFDF)) + name.substring(1); + } + + + /** + *

    This method will attempt to resolve the given EL string.

    + * + * @param context The FacesContext. + * @param elt The LayoutElement associated w/ the expression. + * @param parent The parent UIComponent. This is used + * because the current UIComponent is typically + * unknown (or not even created yet). + * @param value The String (or List / Array) to resolve. + * + * @return The evaluated value (may be null). + */ + public Object resolveValue(FacesContext context, LayoutElement elt, UIComponent parent, Object value) { + // Invoke our own EL. This is needed b/c JSF's EL is designed for + // Bean getters only. It does not get CONSTANTS or pull data from + // other sources without adding a custom VariableResolver and/or + // PropertyResolver. Eventually we may want to find a good way to + // make this work as a regular ValueExpression expression... but for + // now, we'll just resolve it this way. + Object result = VariableResolver.resolveVariables( + context, elt, parent, value); + + // Next check to see if the result contains a JSF ValueExpression + if ((result != null) && (result instanceof String) && isValueReference((String) result)) { + ELContext elctx = context.getELContext(); + ValueExpression ve = + context.getApplication().getExpressionFactory(). + createValueExpression(elctx, (String) result, Object.class); + result = ve.getValue(elctx); +/* +1.1+ + // JSF 1.1 VB: + try { + ValueBinding vb = + context.getApplication().createValueBinding((String) result); + result = vb.getValue(context); + } catch (EvaluationException ex) { + if (LogUtil.infoEnabled()) { + LogUtil.info("JSFT0007", new Object[] {value}); + } + throw ex; + } +*/ + } + + // Return the result + return result; + } + + /** + *

    Returns true if this expression looks like an EL expression.

    + */ + public boolean isValueReference(String value) { + if (value == null) { + return false; + } +// FIXME: Consider adding logic to look for "matching" {}'s + int start = value.indexOf("#{"); + if ((start != -1) && (start < value.indexOf('}', start))) { + return true; + } + return false; + } + + + // While this is static, the information seems reasonable to share across + // applications as it is very unlikely to be different... leaving for now + private static Map _typeCache = + new HashMap(); + + /** + *

    This Map caches ComponentTypes by their factoryClass name.

    + */ + private Map _types = + new HashMap(); + + /** + *

    Application scope key for an instance of + * ComponentUtil.

    + */ + public static final String COMPONENT_UTIL_KEY = "_jsft_COMP_UTIL"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/EventComponent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/EventComponent.java new file mode 100644 index 0000000..a5ede2c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/EventComponent.java @@ -0,0 +1,74 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + + +/** + *

    This UIComponent exists so that custom events may be + * queued and triggered at appropriate times. This will allow + * "beforeEncode", "afterEncode", and even "command" events to be + * associated with components by wrapping 1 or more components with + * this component.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class EventComponent extends TemplateComponentBase { + /** + *

    Constructor for EventComponent.

    + */ + public EventComponent() { + super(); + setRendererType("com.sun.jsftemplating.EventComponent"); + setLayoutDefinitionKey(LAYOUT_KEY); + } + + /** + *

    Return the family for this component.

    + */ + public String getFamily() { + return "com.sun.jsftemplating.EventComponent"; + } + + /** + *

    Restore the state of this component.

    + public void restoreState(FacesContext _context,Object _state) { + Object _values[] = (Object[]) _state; + super.restoreState(_context, _values[0]); + } + */ + + /** + *

    Save the state of this component.

    + public Object saveState(FacesContext _context) { + Object _values[] = new Object[1]; + _values[0] = super.saveState(_context); + return _values; + } + */ + + /** + *

    This is the location of the XML file that declares the layout for + * the EventComponent. (/jsftemplating/event.xml)

    + */ + public static final String LAYOUT_KEY = "/jsftemplating/event.xml"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/ForEach.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/ForEach.java new file mode 100644 index 0000000..62df038 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/ForEach.java @@ -0,0 +1,54 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + + +/** + *

    This UIComponent exists so "foreach" conditions can be + * processed during rendering.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ForEach extends TemplateComponentBase { + /** + *

    Constructor for ForEach.

    + */ + public ForEach() { + super(); + setRendererType("com.sun.jsftemplating.ForEach"); + setLayoutDefinitionKey(LAYOUT_KEY); + } + + /** + *

    Return the family for this component.

    + */ + public String getFamily() { + return "com.sun.jsftemplating.ForEach"; + } + + /** + *

    This is the location of the XML file that declares the layout for + * the ForEach. (/jsftemplating/foreach.xml)

    + */ + public static final String LAYOUT_KEY = "/jsftemplating/foreach.xml"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/If.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/If.java new file mode 100644 index 0000000..f0ad4ff --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/If.java @@ -0,0 +1,54 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + + +/** + *

    This UIComponent exists so "if" conditions can be + * processed during rendering.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class If extends TemplateComponentBase { + /** + *

    Constructor for If.

    + */ + public If() { + super(); + setRendererType("com.sun.jsftemplating.If"); + setLayoutDefinitionKey(LAYOUT_KEY); + } + + /** + *

    Return the family for this component.

    + */ + public String getFamily() { + return "com.sun.jsftemplating.If"; + } + + /** + *

    This is the location of the XML file that declares the layout for + * the If. (/jsftemplating/if.xml)

    + */ + public static final String LAYOUT_KEY = "/jsftemplating/if.xml"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/StaticText.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/StaticText.java new file mode 100644 index 0000000..9229ae3 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/StaticText.java @@ -0,0 +1,53 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + + +/** + *

    This UIComponent produces static text output.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class StaticText extends TemplateComponentBase { + /** + *

    Constructor for StaticText.

    + */ + public StaticText() { + super(); + setRendererType("com.sun.jsftemplating.StaticText"); + setLayoutDefinitionKey(LAYOUT_KEY); + } + + /** + *

    Return the family for this component.

    + */ + public String getFamily() { + return "com.sun.jsftemplating.StaticText"; + } + + /** + *

    This is the location of the XML file that declares the layout for + * the StaticText. (/jsftemplating/staticText.xml)

    + */ + public static final String LAYOUT_KEY = "/jsftemplating/staticText.xml"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponent.java new file mode 100644 index 0000000..7f791f4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponent.java @@ -0,0 +1,97 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; + + +/** + *

    This interface defines additional methods in addition to those defined + * by UIComponent that are needed to work with a TemplateRenderer.

    + * + *

    JSF did not define an interface for UIComponent, so I cannot extend an + * interface here. This means that casting is needed to use UIComponent + * features from a TemplateComponent.

    + * + *

    If you need to have a NamingContainer, do not forget to + * implement that interface in addition to this interface.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface TemplateComponent extends ChildManager { + + /** + * This method will find the request child UIComponent by id. If it is + * not found, it will attempt to create it if it can find a LayoutElement + * describing it. + * + * @param context The FacesContext + * @param id The UIComponent id to search for + * + * @return The requested UIComponent + */ + public UIComponent getChild(FacesContext context, String id); + + /** + * This method returns the LayoutDefinition associated with this component. + * + * @param context The FacesContext + * + * @return LayoutDefinition associated with this component. + */ + public LayoutDefinition getLayoutDefinition(FacesContext context); + + /** + * This method returns the LayoutDefinitionKey for this component. + * + * @return key The key to use in the LayoutDefinitionManager + */ + public String getLayoutDefinitionKey(); + + /** + * This method sets the LayoutDefinition key for this component. + * + * @param key The key to use in the LayoutDefinitionManager + */ + public void setLayoutDefinitionKey(String key); + + /** + *

    This method returns the value of the requested field. It should + * first check the value of field passed in, it should + * return that value if set. Next, it should check to see if there + * is a ValueExpression matching + * attributeName and return that value, if it exists. + * If neither of the first 2 cases yielded a result, + * defaultValue is returned.

    + * + * @param field The field which may contain the value. + * @param attributeName The ValueExpression name. + * @param defaultValue The default value. + * + * @return The value of the property. + */ + public V getPropertyValue(V field, String attributeName, V defaultValue); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponentBase.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponentBase.java new file mode 100644 index 0000000..6934754 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponentBase.java @@ -0,0 +1,165 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIComponentBase; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + *

    This abstract class provides base functionality for components that + * work in conjunction with the + * {@link com.sun.jsftemplating.renderer.TemplateRenderer} that do not + * need any "special" component features (such as provided by + * UIInput, or an ActionSource implementation). + * This class is a suitable class for "container" types of components, or + * components that simply agregate other components together. It + * provides a default implementation of the + * {@link com.sun.jsftemplating.component.TemplateComponent} + * interface.

    + * + * @see com.sun.jsftemplating.renderer.TemplateRenderer + * @see com.sun.jsftemplating.component.TemplateComponent + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public abstract class TemplateComponentBase extends UIComponentBase implements TemplateComponent { + + /** + *

    This method will find the request child UIComponent + * by id. If it is not found, it will attempt to create it if it can + * find a {@link LayoutElement} describing it.

    + * + * @param context The FacesContext. + * @param id The UIComponent id to find. + * + * @return The requested UIComponent. + */ + public UIComponent getChild(FacesContext context, String id) { + return getHelper().getChild(this, context, id); + } + + + /** + *

    This method will find the request child UIComponent + * by id. If it is not found, it will use the given + * {@link LayoutComponent} to create it.

    + * + * @param context The FacesContext. + * @param descriptor The UIComponent id to find. + * + * @return The requested UIComponent. + */ + public UIComponent getChild(FacesContext context, LayoutComponent descriptor) { + return getHelper().getChild(this, context, descriptor); + } + + /** + *

    This method returns the {@link LayoutDefinition} associated with + * this component.

    + * + * @param context The FacesContext. + * + * @return {@link LayoutDefinition} associated with this component. + */ + public LayoutDefinition getLayoutDefinition(FacesContext context) { + return getHelper().getLayoutDefinition(context); + } + + /** + *

    This method saves the state for this component. It relies on the + * superclass to save its own sate, this method will invoke + * super.saveState().

    + * + * @param context The FacesContext. + * + * @return The serialized state. + */ + public Object saveState(FacesContext context) { + return getHelper().saveState(context, super.saveState(context)); + } + + /** + *

    This method restores the state for this component. It will invoke + * the superclass to restore its state.

    + * + * @param context The FacesContext. + * @param state The serialized state. + */ + public void restoreState(FacesContext context, Object state) { + super.restoreState(context, getHelper().restoreState(context, state)); + } + + /** + *

    This method returns the {@link LayoutDefinition} key for this + * component.

    + * + * @return The key to use in the {@link LayoutDefinitionManager}. + */ + public String getLayoutDefinitionKey() { + return getHelper().getLayoutDefinitionKey(); + } + + + /** + *

    This method sets the {@link LayoutDefinition} key for this + * component.

    + * + * @param key The key to use in the {@link LayoutDefinitionManager}. + */ + public void setLayoutDefinitionKey(String key) { + getHelper().setLayoutDefinitionKey(key); + } + + public V getPropertyValue(V field, String attributeName, V defaultValue) { + return getHelper().getAttributeValue(this, field, attributeName, defaultValue); + } + + /** + *

    This method retrieves the {@link TemplateComponentHelper} used by + * this class to help implement the {@link TemplateComponent} + * interface.

    + * + * @return The {@link TemplateComponentHelper} for this component. + */ + protected TemplateComponentHelper getHelper() { + if (_helper == null) { + _helper = new TemplateComponentHelper(); + } + return _helper; + } + + /** + *

    Our TemplateComponentHelper. We initialize it on + * access b/c we want to ensure it exists, if it is serialized it + * won't exist if we init it here or in the constructor.

    + */ + private transient TemplateComponentHelper _helper = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponentHelper.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponentHelper.java new file mode 100644 index 0000000..052c407 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateComponentHelper.java @@ -0,0 +1,264 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIComponentBase; +import javax.faces.context.FacesContext; +import javax.el.ValueExpression; + +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + *

    This class provides base functionality for components that + * work in conjunction with the + * {@link com.sun.jsftemplating.renderer.TemplateRenderer}. It + * provides the bulk of the default implementation of the + * {@link TemplateComponent} interface.

    + * + *

    This class is meant to be used inside a UIComponent class + * that implements TemplateComponent to help provide the + * behavior of a TemplateComponent. It is NOT an + * implementation by itself. A TemplateComonent + * implementation class may use this to help define its functionality and + * must also be an instance of UIComponent.

    + * + * @see com.sun.jsftemplating.renderer.TemplateRenderer + * @see TemplateComponent + * @see TemplateComponentBase + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class TemplateComponentHelper { + + /** + *

    This class should only be used by TemplateComponent + * implementations to help them provide their + * TemplateComponent funtionality.

    + */ + public TemplateComponentHelper() { + } + + /** + *

    This method will find the request child UIComponent by id. If it + * is not found, it will attempt to create it if it can find a + * {@link LayoutElement} describing it.

    + * + * @param context The FacesContext. + * @param id The UIComponent id to find. + * + * @return The requested UIComponent + */ + public UIComponent getChild(UIComponent comp, FacesContext context, String id) { + if ((id == null) || (id.trim().equals(""))) { + // No id, no LayoutComponent, nothing we can do. + return null; + } + + // We have an id, use it to search for an already-created child +// FIXME: I am doing this 2x if it falls through to create the child... +// FIXME: think about optimizing this + UIComponent childComponent = ComponentUtil.getInstance(context).findChild(comp, id, id); + if (childComponent != null) { + return childComponent; + } + + // If we're still here, then we need to create it... hopefully we have + // a LayoutComponent to tell us how to do this! + LayoutDefinition ld = getLayoutDefinition(context); + if (ld == null) { + // No LayoutDefinition to tell us how to create it... return null + return null; + } + + // Attempt to find a LayoutComponent matching the id + LayoutElement elt = + LayoutDefinition.getChildLayoutElementById(context, id, ld, comp); + + // Create the child from the LayoutComponent + return getChild(comp, context, (LayoutComponent) elt); + } + + + /** + *

    This method will find the request child UIComponent + * by id (the id is obtained from the given {@link LayoutComponent}). + * If it is not found, it will attempt to create it from the supplied + * {@link LayoutElement}.

    + * + * @param descriptor The {@link LayoutElement} describing the UIComponent. + * + * @return The requested UIComponent + */ + public UIComponent getChild(UIComponent comp, FacesContext context, LayoutComponent descriptor) { + UIComponent childComponent = null; + + // Sanity check + if (descriptor == null) { + throw new IllegalArgumentException("The LayoutComponent is null!"); + } + + // First pull off the id from the descriptor + String id = descriptor.getId(context, comp); + ComponentUtil compUtil = ComponentUtil.getInstance(context); + if ((id != null) && !(id.trim().equals(""))) { + // We have an id, use it to search for an already-created child + childComponent = compUtil.findChild(comp, id, id); + if (childComponent != null) { + return childComponent; + } + } + + // No id, or the component hasn't been created. In either case, we + // create a new component (moral: always have an id) + + // Invoke "beforeCreate" handlers + descriptor.beforeCreate(context, comp); + + // Create UIComponent + childComponent = + compUtil.createChildComponent(context, descriptor, comp); + + // Invoke "afterCreate" handlers + descriptor.afterCreate(context, childComponent); + + // Return the newly created UIComponent + return childComponent; + } + + /** + *

    This method returns the {@link LayoutDefinition} associated with + * the UIComponent.

    + * + * @param context The FacesContext. + * + * @return {@link LayoutDefinition} associated with the UIComponent. + */ + public LayoutDefinition getLayoutDefinition(FacesContext context) { + // Make sure we don't already have it... + if (_layoutDefinition != null) { + return _layoutDefinition; + } + + // Get the LayoutDefinitionManager key + String key = getLayoutDefinitionKey(); + if (key == null) { + throw new NullPointerException("LayoutDefinition key is null!"); + } + + // Save the LayoutDefinition for future calls to this method + try { + _layoutDefinition = LayoutDefinitionManager. + getLayoutDefinition(context, key); + } catch (LayoutDefinitionException ex) { + throw new IllegalArgumentException( + "A LayoutDefinition was not provided for '" + key + + "'! This is required.", ex); + } + + // Return the LayoutDefinition (if found) + return _layoutDefinition; + } + + /** + *

    This method saves the state for the UIComponent. It + * relies on the UIComponent's superclass to save its own + * sate, and to pass in that Object to this method.

    + * + * @param context The FacesContext. + * @param superState The UIComponent's superclass state. + * + * @return The serialized State. + */ + public Object saveState(FacesContext context, Object superState) { + Object[] values = new Object[2]; + values[0] = superState; + values[1] = _ldmKey; + return values; + } + + /** + *

    This method restores the state for the UIComponent. + * It will return an Object that must be passed to the + * superclass's restoreState method.

    + * + * @param context The FacesContext. + * @param state The serialized state. + * + * @return The State for the superclass to deserialize. + */ + public Object restoreState(FacesContext context, Object state) { + Object[] values = (Object[]) state; + _ldmKey = (java.lang.String) values[1]; + return values[0]; + } + + /** + *

    This method returns the {@link LayoutDefinition} key for the + * UIComponent.

    + * + * @return key The key to use in the {@link LayoutDefinitionManager}. + */ + public String getLayoutDefinitionKey() { + return _ldmKey; + } + + + /** + *

    This method sets the LayoutDefinition key for the + * UIComponent.

    + * + * @param key The key to use in the {@link LayoutDefinitionManager}. + */ + public void setLayoutDefinitionKey(String key) { + _ldmKey = key; + } + + public V getAttributeValue(UIComponent comp, V field, String attributeName, V defaultValue) { + if (field != null) { + return field; + } + ValueExpression ve = comp.getValueExpression(attributeName); + return (ve != null) ? (V) ve.getValue(FacesContext.getCurrentInstance().getELContext()) : + defaultValue; + } + + /** + *

    This is the LayoutDefinition key for the UIComponent. + * This is typically set by the Tag. The Component may also provide + * a default by setting it in its constructor.

    + */ + private String _ldmKey = null; + + + /** + *

    This is a cached reference to the {@link LayoutDefinition} used by + * the UIComponent.

    + */ + private transient LayoutDefinition _layoutDefinition = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateInputComponentBase.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateInputComponentBase.java new file mode 100644 index 0000000..655a156 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateInputComponentBase.java @@ -0,0 +1,161 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIInput; +import javax.faces.context.FacesContext; + + +/** + *

    This abstract class provides base functionality for components that + * work in conjunction with the + * {@link com.sun.jsftemplating.renderer.TemplateRenderer} and would like + * to provide UIInput functionality. It provides a default + * implementation of the {@link TemplateComponent} interface.

    + * + * @see com.sun.jsftemplating.renderer.TemplateRenderer + * @see com.sun.jsftemplating.component.TemplateComponent + * @see com.sun.jsftemplating.component.TemplateComponentHelper + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public abstract class TemplateInputComponentBase extends UIInput implements TemplateComponent { + + /** + *

    This method will find the request child UIComponent + * by id. If it is not found, it will attempt to create it if it can + * find a {@link LayoutElement} describing it.

    + * + * @param context The FacesContext. + * @param id The UIComponent id to find. + * + * @return The requested UIComponent. + */ + public UIComponent getChild(FacesContext context, String id) { + return getHelper().getChild(this, context, id); + } + + + /** + *

    This method will find the request child UIComponent by + * id (the id is obtained from the given {@link LayoutComponent}). If + * it is not found, it will attempt to create it from the supplied + * {@link LayoutElement}.

    + * + * @param context The FacesContext. + * @param descriptor The {@link LayoutElement} describing the UIComponent + * + * @return The requested UIComponent. + */ + public UIComponent getChild(FacesContext context, LayoutComponent descriptor) { + return getHelper().getChild(this, context, descriptor); + } + + /** + *

    This method returns the {@link LayoutDefinition} associated with + * this component.

    + * + * @param context The FacesContext. + * + * @return {@link LayoutDefinition} associated with this component. + */ + public LayoutDefinition getLayoutDefinition(FacesContext context) { + return getHelper().getLayoutDefinition(context); + } + + /** + *

    This method saves the state for this component. It relies on the + * superclass to save its own sate, this method will invoke + * super.saveState().

    + * + * @param context The FacesContext. + * + * @return The serialized state. + */ + public Object saveState(FacesContext context) { + return getHelper().saveState(context, super.saveState(context)); + } + + /** + *

    This method restores the state for this component. It will invoke + * the superclass to restore its state.

    + * + * @param context The FacesContext. + * @param state The serialized state. + */ + public void restoreState(FacesContext context, Object state) { + super.restoreState(context, getHelper().restoreState(context, state)); + } + + /** + *

    This method returns the {@link LayoutDefinition} key for this + * component.

    + * + * @return The key to use in the {@link LayoutDefinitionManager}. + */ + public String getLayoutDefinitionKey() { + return getHelper().getLayoutDefinitionKey(); + } + + + /** + *

    This method sets the {@link LayoutDefinition} key for this + * component.

    + * + * @param key The key to use in the {@link LayoutDefinitionManager}. + */ + public void setLayoutDefinitionKey(String key) { + getHelper().setLayoutDefinitionKey(key); + } + + public V getPropertyValue(V field, String attributeName, V defaultValue) { + return getHelper().getAttributeValue(this, field, attributeName, defaultValue); + } + + /** + *

    This method retrieves the {@link TemplateComponentHelper} used by + * this class to help implement the {@link TemplateComponent} + * interface.

    + * + * @return The {@link TemplateComponentHelper} for this component. + */ + protected TemplateComponentHelper getHelper() { + if (_helper == null) { + _helper = new TemplateComponentHelper(); + } + return _helper; + } + + /** + *

    Our TemplateComponentHelper. We initialize it on + * access b/c we want to ensure it exists, if it is serialized it + * won't exist if we init it here or in the constructor.

    + */ + private transient TemplateComponentHelper _helper = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateOutputComponentBase.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateOutputComponentBase.java new file mode 100644 index 0000000..d92f224 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/TemplateOutputComponentBase.java @@ -0,0 +1,161 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIOutput; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + *

    This abstract class provides base functionality for components that + * work in conjunction with the + * {@link com.sun.jsftemplating.renderer.TemplateRenderer} and would like + * to provide UIInput functionality. It provides a default + * implementation of the {@link TemplateComponent} interface.

    + * + * @see com.sun.jsftemplating.renderer.TemplateRenderer + * @see com.sun.jsftemplating.component.TemplateComponent + * @see com.sun.jsftemplating.component.TemplateComponentHelper + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public abstract class TemplateOutputComponentBase extends UIOutput implements TemplateComponent { + + /** + *

    This method will find the request child UIComponent + * by id. If it is not found, it will attempt to create it if it can + * find a {@link LayoutElement} describing it.

    + * + * @param context The FacesContext. + * @param id The UIComponent id to find. + * + * @return The requested UIComponent. + */ + public UIComponent getChild(FacesContext context, String id) { + return getHelper().getChild(this, context, id); + } + + + /** + *

    This method will find the request child UIComponent by + * id (the id is obtained from the given {@link LayoutComponent}). If + * it is not found, it will attempt to create it from the supplied + * {@link LayoutElement}.

    + * + * @param context The FacesContext. + * @param descriptor The {@link LayoutElement} describing the UIComponent + * + * @return The requested UIComponent. + */ + public UIComponent getChild(FacesContext context, LayoutComponent descriptor) { + return getHelper().getChild(this, context, descriptor); + } + + /** + *

    This method returns the {@link LayoutDefinition} associated with + * this component.

    + * + * @param context The FacesContext. + * + * @return {@link LayoutDefinition} associated with this component. + */ + public LayoutDefinition getLayoutDefinition(FacesContext context) { + return getHelper().getLayoutDefinition(context); + } + + /** + *

    This method saves the state for this component. It relies on the + * superclass to save its own sate, this method will invoke + * super.saveState().

    + * + * @param context The FacesContext. + * + * @return The serialized state. + */ + public Object saveState(FacesContext context) { + return getHelper().saveState(context, super.saveState(context)); + } + + /** + *

    This method restores the state for this component. It will invoke + * the superclass to restore its state.

    + * + * @param context The FacesContext. + * @param state The serialized state. + */ + public void restoreState(FacesContext context, Object state) { + super.restoreState(context, getHelper().restoreState(context, state)); + } + + /** + *

    This method returns the {@link LayoutDefinition} key for this + * component.

    + * + * @return The key to use in the {@link LayoutDefinitionManager}. + */ + public String getLayoutDefinitionKey() { + return getHelper().getLayoutDefinitionKey(); + } + + + /** + *

    This method sets the {@link LayoutDefinition} key for this + * component.

    + * + * @param key The key to use in the {@link LayoutDefinitionManager}. + */ + public void setLayoutDefinitionKey(String key) { + getHelper().setLayoutDefinitionKey(key); + } + + public V getPropertyValue(V field, String attributeName, V defaultValue) { + return getHelper().getAttributeValue(this, field, attributeName, defaultValue); + } + + /** + *

    This method retrieves the {@link TemplateComponentHelper} used by + * this class to help implement the {@link TemplateComponent} + * interface.

    + * + * @return The {@link TemplateComponentHelper} for this component. + */ + protected TemplateComponentHelper getHelper() { + if (_helper == null) { + _helper = new TemplateComponentHelper(); + } + return _helper; + } + + /** + *

    Our TemplateComponentHelper. We initialize it on + * access b/c we want to ensure it exists, if it is serialized it + * won't exist if we init it here or in the constructor.

    + */ + private transient TemplateComponentHelper _helper = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/While.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/While.java new file mode 100644 index 0000000..2cc0eac --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/While.java @@ -0,0 +1,54 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component; + + +/** + *

    This UIComponent exists so "while" conditions can be + * processed during rendering.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class While extends TemplateComponentBase { + /** + *

    Constructor for While.

    + */ + public While() { + super(); + setRendererType("com.sun.jsftemplating.While"); + setLayoutDefinitionKey(LAYOUT_KEY); + } + + /** + *

    Return the family for this component.

    + */ + public String getFamily() { + return "com.sun.jsftemplating.While"; + } + + /** + *

    This is the location of the XML file that declares the layout for + * the While. (/jsftemplating/while.xml)

    + */ + public static final String LAYOUT_KEY = "/jsftemplating/while.xml"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/IndexFieldKey.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/IndexFieldKey.java new file mode 100644 index 0000000..ab40cf5 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/IndexFieldKey.java @@ -0,0 +1,142 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (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.dev.java.net/public/CDDLv1.0.html or + * glassfish/bootstrap/legal/CDDLv1.0.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at glassfish/bootstrap/legal/CDDLv1.0.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.dataprovider; + +import com.sun.data.provider.FieldKey; + + +/** + *

    This implementation of FieldKey provides a way to + * associate an index along with the fieldId. One use case for this is + * when a DataProvider acts as a facade for multiple data sources, the + * index can be used to indicate to which underlying source the key + * pertains.

    + * + *

    Keey in mind that a single FieldKey is meant to represent + * all rows, so it would not be useful to store row information in a + * FieldKey. Therefor the index in this IndexFieldKey is + * not intended to specify a row!

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class IndexFieldKey extends FieldKey { + private static final long serialVersionUID = 1L; + + /** + *

    Constructs a new IndexFieldKey with the specified + * fieldId and index.

    + * + * @param fieldId The desired cannonical ID String. + * @param index The index for this IndexFieldKey. + */ + public IndexFieldKey(String fieldId, int index) { + super(fieldId); + setIndex(index); + } + + /** + *

    Constructs a new IndexFieldKey with the specified + * fieldId, displayName, and + * index.

    + * + * @param fieldId The desired cannonical ID String for this field. + * @param displayName The desired display name String. + * @param index The index for this IndexFieldKey. + */ + public IndexFieldKey(String fieldId, String displayName, int index) { + super(fieldId, displayName); + setIndex(index); + } + + /** + *

    Constructs a new IndexFieldKey with the specified + * fieldId, displayName, and + * index.

    + * + * @param fk The FieldKey. + * @param index The index for this IndexFieldKey. + */ + public IndexFieldKey(FieldKey fk, int index) { + super(fk.getFieldId(), fk.getDisplayName()); + setIndex(index); + } + + /** + *

    This method retreives the index associated with this object.

    + */ + public int getIndex() { + return _index; + } + + /** + *

    This method retreives the index associated with this object.

    + */ + public void setIndex(int idx) { + _index = idx; + } + + /** + *

    Standard equals implementation. This method compares the + * IndexFieldKey fieldId and + * index values for equality.

    + * + * @param obj The Object to check equality. + * + * @return true if equal, false if not. + */ + public boolean equals(Object obj) { + boolean val = super.equals(obj); + if (val && (obj instanceof IndexFieldKey)) { + val = ((IndexFieldKey) obj).getIndex() == getIndex(); + } + return val; + } + + /** + *

    This provides a hash for instances of this class.

    + */ + public int hashCode() { + if (_hash == -1) { + // Use the hashCode() of the String (id + index) + _hash = (getFieldId() + getIndex()).hashCode(); + } + return _hash; + } + + /** + *

    The toString() implementation. This implementation prints out + * the index and fieldId:

    + * + *

    IndexFieldKey[<index>][<id>] + *

    + */ + public String toString() { + return "IndexFieldKey[" + getIndex() + "][" + getFieldId() + "]"; // NOI18N + } + + /** + *

    Storate for the index.

    + */ + private int _index = -1; + private transient int _hash = -1; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MapObjectFieldKeySupport.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MapObjectFieldKeySupport.java new file mode 100644 index 0000000..3134496 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MapObjectFieldKeySupport.java @@ -0,0 +1,208 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (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.dev.java.net/public/CDDLv1.0.html or + * glassfish/bootstrap/legal/CDDLv1.0.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at glassfish/bootstrap/legal/CDDLv1.0.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.dataprovider; + +import java.util.Map; + +import com.sun.data.provider.DataProviderException; +import com.sun.data.provider.FieldKey; +import com.sun.data.provider.impl.ObjectFieldKeySupport; + + +/** + *

    Support class for DataProvider implementations that need + * to instrospect Java classes to discover properties, or Map values and + * return FieldKey instances for them.

    + */ +public class MapObjectFieldKeySupport extends ObjectFieldKeySupport { + + /** + *

    Construct a new support instance wrapping the specified Map class, + * with the specified flag for including public fields.

    + * + * @param cls Class whose properties should be exposed. + * @param inst Optional instance of cls used for + * resolving Map values. + */ + public MapObjectFieldKeySupport(Class cls, Map inst) { + super(cls, false); + if (!Map.class.isAssignableFrom(cls)) { + throw new IllegalArgumentException(this.getClass().getName() + + " is only valid for java.util.Map classes!"); + } + _inst = inst; + } + + /** + *

    Return the FieldKey associated with the specified + * canonical identifier, if any; otherwise, return + * null.

    + * + * @param fieldId Canonical identifier of the required field. + */ + public FieldKey getFieldKey(String fieldId) throws DataProviderException { + FieldKey key = super.getFieldKey(fieldId); + if ((key == null) && (_inst != null)) { + if (_inst.get(fieldId) != null) { + key = new FieldKey(fieldId); + } + } + return key; + } + + /** + *

    Return an array of all supported FieldKeys.

    + */ + public FieldKey[] getFieldKeys() throws DataProviderException { + FieldKey keys[] = super.getFieldKeys(); + if (_inst != null) { + FieldKey tmp[] = new FieldKey[keys.length + _inst.size()]; + int cnt = 0; + // Add all other keys + for (FieldKey key : keys) { + tmp[cnt++] = key; + } + + // Add all Map keys + for (Object key : _inst.keySet()) { + tmp[cnt++] = new FieldKey(key.toString()); + } + keys = tmp; + } + return keys; + } + + /** + *

    Return the type of the field associated with the specified + * FieldKey, if it can be determined; otherwise, return + * null.

    + * + * @param fieldKey FieldKey to return the type for. + */ + public Class getType(FieldKey fieldKey) throws DataProviderException { + Class type = super.getType(fieldKey); + if (type == null) { + Object obj = _inst.get(fieldKey.getFieldId()); + if (obj != null) { + type = obj.getClass(); + } + } + return type; + } + + + /** + *

    Return the value for the specified FieldKey, from the + * specified base object.

    + * + * @param fieldKey FieldKey for the requested field. + * @param base Base object to be used. + */ + public Object getValue(FieldKey fieldKey, Object base) throws DataProviderException { + // Make sure we have an instance + if (base != null) { + _inst = (Map) base; + } + if (_inst == null) { + return null; + } + + // Check the properties (super behavior) + Object val = super.getValue(fieldKey, _inst); + + // If not found, check the Map + if (val == null) { + val = _inst.get(fieldKey.getFieldId()); + } + + // Return the result (if found, null otherwise) + return val; + } + + + /** + *

    Return true if the specified value may be successfully + * assigned to the specified field. The only time this is false is if + * a property of the Map implementation is being set. Map values can + * be any Object and therefor will always be true.

    + * + * @param fieldKey FieldKey to check assignability for. + * @param value Proposed value. + */ + public boolean isAssignable(FieldKey fieldKey, Object value) throws DataProviderException { + Class type = super.getType(fieldKey); + if (type != null) { + // We only do this if we have a property... + return super.isAssignable(fieldKey, value); + } + + // Return true in all other cases + return true; + } + + /** + *

    Return the read only state of the field associated with the + * specified FieldKey, if it can be determined, + * otherwise, return false.

    + * + * @param fieldKey FieldKey to return read only state for + */ + public boolean isReadOnly(FieldKey fieldKey) throws DataProviderException { + Class type = super.getType(fieldKey); + if (type != null) { + // We only do this if we have a property... + return super.isReadOnly(fieldKey); + } + return false; + } + + + /** + *

    Set the value for the specified fieldKey, + * on the specified base object. If the instance + * (base) is already set on this support object, then + * base may be null.

    + * + * @param fieldKey FieldKey for the requested field. + * @param base Base object to be used (null ok if already set). + * @param value Value to set. + * + * @exception NullPointerException If base and _inst are null. + * @exception IllegalArgumentException If a type mismatch occurs. + * @exception IllegalStateException If setting a read only field. + */ + public void setValue(FieldKey fieldKey, Object base, Object value) throws DataProviderException { + if (base != null) { + _inst = (Map) base; + } + Class type = super.getType(fieldKey); + if (type != null) { + // We only do this if we have a property... + super.setValue(fieldKey, _inst, value); + } else { + _inst.put(fieldKey.getFieldId(), value); + } + } + + private Map _inst = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MultipleListDataProvider.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MultipleListDataProvider.java new file mode 100644 index 0000000..1745d66 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MultipleListDataProvider.java @@ -0,0 +1,636 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (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.dev.java.net/public/CDDLv1.0.html or + * glassfish/bootstrap/legal/CDDLv1.0.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at glassfish/bootstrap/legal/CDDLv1.0.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.dataprovider; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import com.sun.data.provider.DataProviderException; +import com.sun.data.provider.FieldKey; +import com.sun.data.provider.RowKey; +import com.sun.data.provider.TransactionalDataListener; +import com.sun.data.provider.impl.IndexRowKey; +import com.sun.data.provider.impl.ObjectFieldKeySupport; +import com.sun.data.provider.impl.ObjectListDataProvider; + + +/** + *

    This implementation allows for multiple List objects to + * be used to represent table rows. If mulitiple Lists are + * used, they must be parallel lists (i.e. have the same # and order of + * information).

    + */ +public class MultipleListDataProvider extends ObjectListDataProvider { + private static final long serialVersionUID = 1L; + + /** + *

    Default Constructor.

    + */ + public MultipleListDataProvider() { + setIncludeFields(false); + } + + /** + *

    Constructor that creates initializes the DataProvider with a + * single List. Fields are not included by + * default.

    + * + * @param list Primary list containing row information. + */ + public MultipleListDataProvider(List> list) { + this(list, false); + } + + /** + *

    Constructor that creates initializes the DataProvider with a + * single List. Fields are included if + * includeFields is true.

    + * + * @param lists List<List<Object>> to be + * wrapped. + * @param includeFields Desired include fields property setting + */ + public MultipleListDataProvider(List> lists, boolean includeFields) { + // Set the lists + setLists(lists); + + // Do not include fields + setIncludeFields(false); + } + + /** + *

    Constructor for an empty DataProvider with a known + * type. This constructor is only useful when there is a single + * List. Fields are not included.

    + * + * @param objectTypes Desired object type Classes. + */ + public MultipleListDataProvider(Class [] objectTypes) { + this(objectTypes, false); + } + + /** + *

    Constructor for an empty DataProvider with a known + * type. This constructor is only useful when there is a single + * List. Fields are included if + * includeFields is true.

    + * + * @param objTypes Desired object type of Classes + * @param includeFields Desired include fields property setting + */ + public MultipleListDataProvider(Class [] objTypes, boolean includeFields) { + setObjectTypes(objTypes); + setIncludeFields(includeFields); + } + +// FIXME: Provide apis to manage multiple lists: +// FIXME: addList(String, List) +// FIXME: removeList(String)?? + + /** + *

    This method returns an array of Object + * (Object []) for the given row. Each + * array element cooresponds to an Object in one of the + * Lists represented by this instance of + * MultipleListDataProvider.

    + * + * @throws IndexOutOfBoundsException If row is invalid. + */ + public Object getObject(RowKey row) { + if (!isRowAvailable(row)) { + throw new IndexOutOfBoundsException("" + row); + } + int rowIdx = getRowIndex(row); + List> lists = getLists(); + Object [] result = new Object[lists.size()]; + int idx = 0; + for (List list : lists) { + result[idx++] = list.get(rowIdx); + } + return result; + } + + /** + *

    This method returns an array of array ofObjects + * (Object [][]). The first element of the array is the + * row, the second cooresponds to the List: + * Object[row #][list #]. If there is only one + * List represented by this instance of + * MultipleListDataProvider, then the list # will be 0; + * if there are 2 Lists, then the list # will be 0 or 1, + * etc.

    + */ + public Object [] getObjects() { + // Get the array demensions + List> lists = getLists(); + int numLists = lists.size(); + if (numLists == 0) { + // This isn't likely, but just in case... + return new Object[0][0]; + } + int numRows = lists.get(0).size(); + Object [][] result = new Object[numRows][numLists]; + + // Fill the array + int listNum = 0; + for (int rowNum = 0; rowNum < numRows; rowNum++) { + listNum = 0; + for (List list : lists) { + result[rowNum][listNum++] = list.get(rowNum); + } + } + + // Return the result (Object[rows][lists]) + return result; + } + + /** + *

    This sets the Object type contained in the + * List that this MulitpleObjectDataProvider + * represents. This method should only be used when there is one + * List held by this + * MultipleListDataProvider. In cases where you have + * more than one list (and likely you do because you are using this + * DataProvider), you should use + * {@link #setObjectTypes(Class [])}.

    + */ + public void setObjectType(Class objectType) { + setObjectTypes(new Class [] {objectType}); + } + + + /** + *

    This method sets the Object types for each List that + * is represented by this instance of this class. By doing this, you + * allow the FieldKeys to be generated. You only need to specify this + * information if you have no rows. If there is some data, that data + * will be used to determine the type.

    + * + * @param objectTypes The Class types of the row data. + */ + public void setObjectTypes(Class [] objectTypes) { + _types = objectTypes; + } + + /** + *

    Not supported. This method does not appear to have great value.

    + */ + public void removeObject(Object object) { + throw new UnsupportedOperationException(); + } + + /** + *

    Not yet supported.

    + * + * @param row The RowKey of the row to check. + */ + public boolean isRemoved(RowKey row) { + return _deletes.contains(row); + } + + /** + *

    Replace the object at the specified row.

    + * + * @param row The desired row to set the contained object + * @param object The new object to set at the specified row + */ + public void setObject(RowKey row, Object object) { + throw new UnsupportedOperationException(this.getClass().getName() + + " does not support the setObject(RowKey, Object) method. " + + "Instead use setObjects(RowKey, Object [])."); + } + + /** + *

    This method allows the given row to be replaced with + * the given objects.

    + * + * @param row The row to replace. + * @param objects The array of Objects to use. + */ + public void setObjects(RowKey row, Object [] objects) { + Object [] previous = (Object []) getObject(row); + int rowNum = getRowIndex(row); + int cnt = 0; + for (List list : getLists()) { + list.set(rowNum, objects[cnt++]); + } + fireValueChanged(null, row, previous, objects); + if (getCursorRow() == row) { + fireValueChanged(null, previous, objects); + } + } + + /** + *

    Not yet supported...

    + */ + public void addObject(Object object) { +// FIXME: Add api to add the Object*s* (see addObject(object), must have 1 for each List + throw new UnsupportedOperationException(); + } + + // ---------------------------------------------------- DataProvider Methods + + + /** + * + */ + public FieldKey getFieldKey(String fieldId) throws DataProviderException { + return getSupport().getFieldKey(fieldId); + } + + + /** + * + */ + public FieldKey [] getFieldKeys() throws DataProviderException { + return getSupport().getFieldKeys(); + } + + /** + * + */ + public Class getType(FieldKey fieldKey) throws DataProviderException { + return getSupport().getType(fieldKey); + } + + /** + * + */ + public boolean isReadOnly(FieldKey fieldKey) throws DataProviderException { + return getSupport().isReadOnly(fieldKey); + } + +// FIXME: The following method is very difficult to implement correctly b/c +// FIXME: the super class uses its own private "getSupport()" method which will +// FIXME: return the wrong "support" class. However, the superclass is also +// FIXME: managing the "updates" so we must call it... Ask Creator group to +// FIXME: properly expose "support" via an interface and get/setSupport() +// FIXME: methods. Or ask them to provide access to the updates/deletes/etc. +// FIXME: properties. +// +// FIXME: OK... it appears that they ObjectListDataProvider does not utilize the FieldKey methods in its superclass and instead maintains a private list via its support class. This means I cannot do anything to make this method work with updates!!! + /** + * + */ + public Object getValue(FieldKey fieldKey, RowKey rowKey) throws DataProviderException { + Object val = null; + try { + // This will try to get the value, but is unlikely to succeed... + val = super.getValue(fieldKey, rowKey); + } catch(Exception ex) { + // Now check the "right" support class... + if (getSupport().getFieldKey(fieldKey.getFieldId()) == null) { + throw new IllegalArgumentException("" + fieldKey); + } + + // Make sure it's a valid row key... + if (!isRowAvailable(rowKey)) { + throw new IndexOutOfBoundsException("" + rowKey); + } + int index = getRowIndex(rowKey); + if (index < getRowCount()) { + val = getSupport().getValue( + fieldKey, getListForFieldKey(fieldKey).get(index)); + } else { +// FIXME: Need to manually implement appends, updates, and deletes!! :( +// return getSupport().getValue(fieldKey, appends.get(index - getRowCount())); + } + } + return val; + } + + /** + * + */ + public void setValue(FieldKey fieldKey, RowKey rowKey, Object value) throws DataProviderException { + if (getSupport().getFieldKey(fieldKey.getFieldId()) == null) { + throw new IllegalArgumentException("" + fieldKey); + } + if (getSupport().isReadOnly(fieldKey)) { + throw new IllegalStateException("" + fieldKey); + } + if (!isRowAvailable(rowKey)) { + throw new IndexOutOfBoundsException("" + rowKey); + } + + // Retrieve the previous value and determine if it has changed + Object previous = getValue(fieldKey, rowKey); + if (((previous == null) && (value == null)) || + ((previous != null) && (value != null) && previous.equals(value))) { + return; // No change + } + + // Verify type compatibility of the proposed new value + if (!getSupport().isAssignable(fieldKey, value)) { + throw new IllegalArgumentException(fieldKey + " = " + value); // NOI18N + } + +// FIXME: Need to explicitly support updates (can't get via polymorphism due to bad design)! :( +/* + // Record a pending change for this row and field + Map fieldUpdates = (Map) updates.get(rowKey); + if (fieldUpdates == null) { + fieldUpdates = new HashMap(); + updates.put(rowKey, fieldUpdates); + } + fieldUpdates.put(fieldKey, value); +*/ + //Remove the following set line and defer until commit() once updates/deletes/etc. is worked out + int index = getRowIndex(rowKey); + getSupport().setValue( + fieldKey, getListForFieldKey(fieldKey).get(index), value); + + fireValueChanged(fieldKey, rowKey, previous, value); + fireValueChanged(fieldKey, previous, value); + } + + /** + *

    Construct new instances for each List represented by + * this class and appended them to each List. + */ + public RowKey appendRow() throws DataProviderException { +// FIXME: Support this! + throw new UnsupportedOperationException(); + } + + /** + *

    This method returns true if rows may be appended.

    + */ + public boolean canAppendRow() throws DataProviderException { + return (isUserResizable() && (getObjectTypes() != null)); + } + + /** + *

    This method is not supported.

    + * + * @param object Object to be appended. + */ + public RowKey appendRow(Object object) throws DataProviderException { +// FIXME: Support this! + throw new UnsupportedOperationException(); + } + + /** + *

    Remove the object at the specified row from the list.

    + * + * {@inheritDoc} + */ + public void removeRow(RowKey rowKey) throws DataProviderException { + // Verify we can actually remove this row + if (!canRemoveRow(rowKey)) { +// FIXME: I18N + throw new IllegalStateException( + "This ObjectListDataProvider is not resizable."); + } + if (!isRowAvailable(rowKey)) { +// FIXME: I18N + throw new IllegalArgumentException( + "Cannot delete row for row key " + rowKey); + } + + // Record the fact that we are going to delete this row + _deletes.add(rowKey); + + // Fire appropriate events regarding this deletion + fireRowRemoved(rowKey); + if (getCursorRow() == rowKey) { + fireValueChanged(null, getObject(rowKey), null); + } + } + + /** + *

    This method returns the # of rows represented by this + * MultipleListDataProvider.

    + */ + public int getRowCount() throws DataProviderException { + List> lists = getLists(); + int count = 0; + if ((lists != null) && (lists.size() != 0)) { + count = lists.get(0).size(); + } + return count; + } + + /** + *

    Return true if the specified RowKey + * represents a row in the original list, or a row that has been + * appended.

    + * + * @param row RowKey to test for availability. + */ + public boolean isRowAvailable(RowKey row) throws DataProviderException { + int idx = getRowIndex(row); + if (idx < 0) { + return false; + } + if (idx < (getRowCount() /* + appendCount */)) { + return true; + } + return false; + } + + // --------------------------------------- TransactionalDataProvider Methods + /** + *

    Cause any cached updates to existing field values, as well as + * inserted and deleted rows, to be flowed through to the underlying + * Lists wrapped by this DataProvider.

    + */ + public void commitChanges() throws DataProviderException { + // FIXME: Do updates here... (see super()) + + // Commit pending deletes + // Iterate backwards so that we correctly modify List + RowKey deletes[] = (RowKey[]) + _deletes.toArray(new RowKey[_deletes.size()]); + int rowIdx = -1; + for (int idx = (deletes.length - 1); idx >= 0; idx--) { + rowIdx = getRowIndex(deletes[idx]); + for (List list : getLists()) { + list.remove(rowIdx); + } + } + _deletes.clear(); + + // FIXME: Deal w/ appends (see super()) + + // Notify interested listeners that we have committed + fireChangesCommitted(); + } + + /** + *

    Fire a changesCommitted method to all registered + * listeners.

    + */ + protected void fireChangesCommitted() { +// FIXME: This method overrides a method by the same name in the superclass that is private! The super() should make this protected. + TransactionalDataListener listeners[] = getTransactionalDataListeners(); + for (int i = 0; i < listeners.length; i++) { + listeners[i].changesCommitted(this); + } + } + + + /** + *

    Fire a changesReverted method to all registered + * listeners.

    + */ + private void fireChangesReverted() { +// FIXME: This method overrides a method by the same name in the superclass that is private! The super() should make this protected. + TransactionalDataListener listeners[] = getTransactionalDataListeners(); + for (int i = 0; i < listeners.length; i++) { + listeners[i].changesReverted(this); + } + } + + /** + * + */ + public void revertChanges() throws DataProviderException { + // FIXME: Do updates here... (see super()) + //updates.clear(); + + _deletes.clear(); + + // FIXME: Deal w/ appends + //appends.clear(); + + // Notify interested listeners that we are reverting + fireChangesReverted(); + } + + /** + *

    Accessor for the List of Lists.

    + */ + public List> getLists() { + return _lists; + } + + /** + *

    Setter for the List of Lists.

    + */ + public void setLists(List> lists) { + _lists = lists; + } + + /** + *

    This method returns + */ + public List getListForFieldKey(FieldKey key) { + if ((key != null) && !(key instanceof IndexFieldKey)) { + key = support.getFieldKey(key.getFieldId()); + } + if (key == null) { + throw new IllegalArgumentException("Invalid FieldKey: " + key); + } + return getLists().get(((IndexFieldKey) key).getIndex()); + } + + /** + *

    The cached support object for field key manipulation. Must be + * transient because its content is not Serializable.

    + */ + private transient MultipleObjectFieldKeySupport support = null; + + + /** + *

    Return the {@link ObjectFieldKeySupport} instance for the object + * class we are wrapping.

    + */ + private MultipleObjectFieldKeySupport getSupport() { + if (support == null) { + // Try to get first element of the list to help find FieldKeys + Object [] objs = (Object []) getObject(getRowKey(0)); + if ((objs != null) && (objs.length > 0)) { + support = new MultipleObjectFieldKeySupport( + objs, isIncludeFields()); + } +// else { +// FIXME: Add ability to use other meta information (i.e. _types and/or special class to describe info (i.e. for Maps)) to do this. +// } + } + return support; + } + + /** + *

    This method converts the given rowKey to an + * int.

    + */ + protected int getRowIndex(RowKey rowKey) { +// FIXME: This method overrides a private method by the same name... that method shouldn't be private! + if (rowKey instanceof IndexRowKey) { + return ((IndexRowKey) rowKey).getIndex(); + } + return -1; + } + + /** + *

    This method converts the given int to a + * RowKey.

    + */ + protected RowKey getRowKey(int index) { + return new IndexRowKey(index); + } + + + //////////////////////////////////////////////////////////////////////// + // Unsupported Methods + //////////////////////////////////////////////////////////////////////// + + /** + *

    This method is not supported.

    + */ + public Class getObjectType() { + throw new UnsupportedOperationException(this.getClass().getName() + + " does not support the getObjectType() method because it " + + "must return multiple types. Please use \"Class [] " + + "getObjectTypes()\" instead."); + } + + /** + *

    This method returns an array of Class [] representing + * the Object types represented by this instance of this + * class.

    + */ + public Class [] getObjectTypes() { + return _types; + } + + /** + *

    Storage for our List of Lists.

    + */ + private List> _lists = new ArrayList>(); + + /** + *

    Type information for the LIsts.

    + */ + private Class [] _types = null; + + /** + *

    Set of {@link RowKey}s marked to be deleted. An + * Iterator over this set will return the corresponding + * {@link RowKey}s in ascending order.

    + */ + protected Set _deletes = new TreeSet(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MultipleObjectFieldKeySupport.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MultipleObjectFieldKeySupport.java new file mode 100644 index 0000000..2ea483e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/MultipleObjectFieldKeySupport.java @@ -0,0 +1,248 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (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.dev.java.net/public/CDDLv1.0.html or + * glassfish/bootstrap/legal/CDDLv1.0.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at glassfish/bootstrap/legal/CDDLv1.0.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.dataprovider; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import com.sun.data.provider.DataProviderException; +import com.sun.data.provider.FieldKey; +import com.sun.data.provider.impl.ObjectFieldKeySupport; + + +/** + *

    Support class for DataProvider implementations that need + * to instrospect Java classes to discover properties, Map values, or + * public fields (optional) and return FieldKey instances for + * them. This implementation provides support for multiple Objects.

    + */ +public class MultipleObjectFieldKeySupport { + + /** + *

    Construct a new support instance wrapping the specified classes, + * with the specified flag for including public fields.

    + * + * @param classes Class whose properties should be exposed. + * @param includeFields Flag indicating whether public fields should + * also be included. + public MultipleObjectFieldKeySupport(Class classes[], boolean includeFields) { + for (Class cls : classes) { + } + } + */ + + /** + *

    Construct a new support instance wrapping the specified objects, + * with the specified flag for including public fields.

    + * + * @param objs Class whose properties should be exposed. + * @param includeFields Flag indicating whether public fields should + * also be included. + */ + public MultipleObjectFieldKeySupport(Object objs[], boolean includeFields) { + _children = new ArrayList(); + for (Object obj : objs) { + if (obj instanceof Map) { + _children.add( + new MapObjectFieldKeySupport(obj.getClass(), (Map) obj)); + } else { + _children.add( + new ObjectFieldKeySupport(obj.getClass(), includeFields)); + } + } + } + + /** + *

    Return the FieldKey associated with the specified + * canonical identifier, if any; otherwise, return + * null.

    + * + * @param fieldId Canonical identifier of the required field. + */ + public FieldKey getFieldKey(String fieldId) throws DataProviderException { + FieldKey key = null; + int idx = 0; + for (ObjectFieldKeySupport support : _children) { + key = support.getFieldKey(fieldId); + if (key != null) { + key = new IndexFieldKey(key, idx); + break; + } + idx++; + } + return key; + } + + + /** + *

    Return an array of all supported FieldKeys.

    + */ + public FieldKey[] getFieldKeys() throws DataProviderException { + Set keys = new TreeSet(); + FieldKey keyArr[] = null; + int idx = 0; + for (ObjectFieldKeySupport support : _children) { + keyArr = support.getFieldKeys(); + for (int cnt = 0; cnt < keyArr.length; cnt++) { + keyArr[cnt] = new IndexFieldKey(keyArr[cnt], idx++); + } + keys.addAll(Arrays.asList(keyArr)); + } + return keys.toArray(new FieldKey[keys.size()]); + } + + + /** + *

    Return the type of the field associated with the specified + * FieldKey, if it can be determined; otherwise, return + * null.

    + * + * @param fieldKey FieldKey for which to return the type. + */ + public Class getType(FieldKey fieldKey) throws DataProviderException { + Class type = null; + if (fieldKey instanceof IndexFieldKey) { + type = _children.get(((IndexFieldKey) fieldKey).getIndex()). + getType(fieldKey); + } else { + for (ObjectFieldKeySupport support : _children) { + type = support.getType(fieldKey); + if (type != null) { + break; + } + } + } + return type; + } + + /** + *

    Return the value for the specified FieldKey, from the + * specified base object.

    + * + * @param fieldKey FieldKey for the requested field. + * @param base Base object to be used. + */ + public Object getValue(FieldKey fieldKey, Object base) throws DataProviderException { + Object value = null; + if (fieldKey instanceof IndexFieldKey) { + value = _children.get(((IndexFieldKey) fieldKey).getIndex()). + getValue(fieldKey, base); + } else { + for (ObjectFieldKeySupport support : _children) { + value = support.getValue(fieldKey, base); + if (value != null) { + break; + } + } + } + return value; + } + + /** + *

    Return true if the specified value may be successfully + * assigned to the specified field.

    + * + * @param fieldKey FieldKey to check assignability. + * @param value Proposed value. + */ + public boolean isAssignable(FieldKey fieldKey, Object value) throws DataProviderException { + boolean assignable = false; + if (fieldKey instanceof IndexFieldKey) { + assignable = _children.get(((IndexFieldKey) fieldKey).getIndex()). + isAssignable(fieldKey, value); + } else { + for (ObjectFieldKeySupport support : _children) { + assignable = support.isAssignable(fieldKey, value); + if (assignable) { + break; + } + } + } + return assignable; + } + + /** + *

    Return the read only state of the field associated with the + * specified FieldKey, if it can be determined, + * otherwise, return true.

    + * + * @param fieldKey FieldKey to check. + */ + public boolean isReadOnly(FieldKey fieldKey) throws DataProviderException { + boolean readOnly = true; + if (fieldKey instanceof IndexFieldKey) { + readOnly = _children.get(((IndexFieldKey) fieldKey).getIndex()). + isReadOnly(fieldKey); + } else { + FieldKey fk = null; + for (ObjectFieldKeySupport support : _children) { + fk = support.getFieldKey(fieldKey.getFieldId()); + if (fk != null) { + // Only call support for the one that claims it has a FieldKey! + readOnly = support.isReadOnly(fieldKey); + break; + } + } + } + return readOnly; + } + + + /** + *

    Set the value for the specified FieldKey, on the + * specified base object.

    + * + * @param fieldKey FieldKey for the requested field. + * @param base Base object to be used. + * @param value Value to be set. + * + * @exception IllegalArgumentException If a type mismatch occurs + * @exception IllegalStateException If setting a read only field + * is attempted. + */ + public void setValue(FieldKey fieldKey, Object base, Object value) throws DataProviderException { + if (fieldKey instanceof IndexFieldKey) { + _children.get(((IndexFieldKey) fieldKey).getIndex()). + setValue(fieldKey, base, value); + } else { + FieldKey fk = null; + for (ObjectFieldKeySupport support : _children) { + fk = support.getFieldKey(fieldKey.getFieldId()); + if (fk != null) { + // Only call support for the one that claims it has a FieldKey! + support.setValue(fieldKey, base, value); + break; + } + } + } + } + + /** + *

    This list hold the child ObjectFieldKeySupport implementations.

    + */ + private List _children = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/README.txt b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/README.txt new file mode 100644 index 0000000..0302348 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/dataprovider/README.txt @@ -0,0 +1,17 @@ +The files in this directory extend the capabilities of the DataProvider API. +The Woodstock (sun) and Creator (rave) components make use of the +dataprovider APIs. + +Data Provider APIs are part of Visual web Pack (also part of Java Studio +Creator). You can get the sources for the dataproviders from VisualWeb module +that is open sourced as a sub project on netbeans.org. You can either download +a source bundle or checkout the sources. Instructions are here: + + http://visualweb.netbeans.org/ + +Once you have the sources, you will find the data provider sources under: + + visualweb\dataprovider\runtime\library\src\com\sun\data\provider + + + (above instructions from Jayashri) diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ComponentFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ComponentFactory.java new file mode 100644 index 0000000..7d2589c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ComponentFactory.java @@ -0,0 +1,76 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory; + +import java.io.Serializable; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This interface must be implemented by all UIComponent factories. + * This enabled UIComponents to be created via a consistent interface. + * This is critical to classes such as + * {@link com.sun.jsftemplating.component.TemplateComponentBase} + * and {@link LayoutComponent}.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface ComponentFactory { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created UIComponent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent); + + /** + *

    This method returns the extraInfo that was set for this + * ComponentFactory from the + * {@link com.sun.jsftemplating.layout.descriptors.ComponentType}.

    + */ + public Serializable getExtraInfo(); + + /** + *

    This method is invoked from the + * {@link com.sun.jsftemplating.layout.descriptors.ComponentType} to + * provide more information to the factory. For example, if the JSF + * component type was passed in, a single factory class could + * instatiate multiple components the extra info that is passed in.

    + * + *

    Some factory implementations may want to use this method to + * execute intialization code for the factory based in the value + * passed in.

    + */ + public void setExtraInfo(Serializable extraInfo); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ComponentFactoryBase.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ComponentFactoryBase.java new file mode 100644 index 0000000..ae3c0d6 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ComponentFactoryBase.java @@ -0,0 +1,295 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.el.ValueExpression; +import javax.faces.component.ActionSource; +import javax.faces.component.EditableValueHolder; +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.el.VariableResolver; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.event.CommandActionListener; +import com.sun.jsftemplating.layout.event.ValueChangeListener; +import com.sun.jsftemplating.util.LogUtil; + + +/** + *

    This abstract class provides common functionality for UIComponent + * factories.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public abstract class ComponentFactoryBase implements ComponentFactory { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created UIComponent. + */ + public abstract UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent); + + /** + *

    This method iterates through the Map of options. It looks at each + * one, if it contians an EL expression, it sets a value binding. + * Otherwise, it calls setAttribute() on the component (which in turn + * will invoke the bean setter if there is one).

    + * + *

    This method also interates through the child + * LayoutElements of the given {@link LayoutComponent} + * descriptor and adds Facets or children as appropriate.

    + * + * @param context The FacesContext + * @param desc The {@link LayoutComponent} descriptor associated with + * the requested UIComponent. + * @param comp The UIComponent + */ + protected void setOptions(FacesContext context, LayoutComponent desc, UIComponent comp) { + if (desc == null) { + // Nothing to do + return; + } + + // First set the id if supplied, treated special b/c the component + // used for ${} expressions is the parent and this must be set first + // so other ${} expressions can use $this{id} and $this{clientId}. + String compId = (String) desc.getId(context, comp.getParent()); + if ((compId != null) && (!compId.equals(""))) { + comp.setId(compId); + } + + // Loop through all the options and set the values +// FIXME: Figure a way to skip options that should not be set on the Component + Iterator it = desc.getOptions().keySet().iterator(); + String key = null; + while (it.hasNext()) { + // Get next property + key = it.next(); + + setOption(context, comp, desc, key, desc.getOption(key)); + } + + // Check for "command" handlers... + List handlers = desc.getHandlers(LayoutComponent.COMMAND); + if ((handlers != null) && (comp instanceof ActionSource)) { + ((ActionSource) comp).addActionListener( + CommandActionListener.getInstance()); + } + + // Check for "valueChange" handlers... + handlers = desc.getHandlers(ValueChangeListener.VALUE_CHANGE); + if ((handlers != null) && (comp instanceof EditableValueHolder)) { + ((EditableValueHolder) comp).addValueChangeListener( + ValueChangeListener.getInstance()); + } + + // Set the events on the new component + storeInstanceHandlers(desc, comp); + } + + /** + *

    This method sets an individual option on the + * UIComponent. It will check to see if it is a + * ValueExpression, if it is it will store it as + * such.

    + */ + protected void setOption(FacesContext context, UIComponent comp, LayoutComponent desc, String key, Object value) { + ComponentUtil.getInstance(context).setOption(context, key, value, desc, comp); + } + + /** + *

    This method is responsible for interating over the "instance" + * handlers and applying them to the UIComponent. An "instance" + * handler is one that is defined outside a renderer, or a + * nested component within a renderer. In other words, a handler + * that would not get fired by the TemplateRenderer. By passing this + * in via the UIComponent, code that is aware of events (see + * {@link com.sun.jsftemplating.layout.descriptors.LayoutElementBase}) + * may find these events and fire them. These may vary per "instance" + * of a particular component (i.e. TreeNode) unlike the + * handlers defined in a TemplateRender's XML (which are shared and + * therefor should not change dynamically).

    + * + *

    This method is invoked from setOptions(), however, if setOptions + * is not used in by a factory, this method may be invoked directly. + * Calling this method multiple times will not cause any harm, + * besides making an extra unnecessary call.

    + * + * @param desc The descriptor potentially containing handlers to copy. + * @param comp The UIComponent instance to store the handlers. + */ + protected void storeInstanceHandlers(LayoutComponent desc, UIComponent comp) { + if (!desc.isNested()) { + UIComponent parent = comp.getParent(); + if ((parent == null) || (parent instanceof UIViewRoot)) { + // This is not a nested LayoutComponent, it should not store + // instance handlers + // NOTE: could skip TemplateComponent children also. Although + // this is harder to detect as dynamic children aren't + // defined in the template and therefor must be stored in + // the UIComponent tree. + return; + } + } + + // Iterate over the instance handlers + Iterator it = desc.getHandlersByTypeMap().keySet().iterator(); + if (it.hasNext()) { + String eventType = null; + Map compAttrs = comp.getAttributes(); + while (it.hasNext()) { + // Assign instance handlers to attribute for retrieval later + // (NOTE: retrieval must be explicit, see LayoutElementBase) + eventType = it.next(); + if (eventType.equals(LayoutComponent.BEFORE_CREATE)) { + // This is handled directly, no need for instance handler + continue; + } else if (eventType.equals(LayoutComponent.AFTER_CREATE)) { + // This is handled directly, no need for instance handler + continue; + } + compAttrs.put(eventType, desc.getHandlers(eventType)); + } + } + } + + /** + *

    This method associates the given child with the given parent. By + * using this method we centralize the code so that if we decide + * later to add it as a real child it can be done in one place.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * @param child The child UIComponent + */ + protected void addChild(FacesContext context, LayoutComponent descriptor, UIComponent parent, UIComponent child) { + // Check to see if we should add this as a facet. NOTE: We add + // UIViewRoot children as facets b/c we render them via the + // LayoutElement tree. + String facetName = descriptor.getFacetName(parent); + if (facetName != null) { + // Add child as a facet... + if (LogUtil.configEnabled() && facetName.equals("_noname")) { + // Warn the developer that they may have a problem + LogUtil.config("Warning: no id was supplied for " + + "component '" + child + "'!"); + } + // Resolve the id if its dynamic + facetName = (String) ComponentUtil.getInstance(context).resolveValue( + context, descriptor, child, facetName); + parent.getFacets().put(facetName, child); + } else { + // Add this as an actual child + parent.getChildren().add(child); + } + } + + /** + *

    This method instantiates the UIComponent given its + * ComponentType. It will respect the + * binding property so that a UIComponent + * can be created via the binding property. While a + * custom {@link ComponentFactory} can do a better job, at times it + * may be desirable to use binding instead.

    + */ + protected UIComponent createComponent(FacesContext ctx, String componentType, LayoutComponent desc, UIComponent parent) { + UIComponent comp = null; + + // Check for the "binding" property + String binding = null; + if (desc != null) { + binding = + (String) desc.getEvaluatedOption(ctx, "binding", parent); + } + if ((binding != null) && ComponentUtil.getInstance(ctx).isValueReference(binding)) { + // Create a ValueExpression + ValueExpression ve = + ctx.getApplication().getExpressionFactory(). + createValueExpression( + ctx.getELContext(), binding, UIComponent.class); + // Create / get the UIComponent + comp = ctx.getApplication().createComponent( + ve, ctx, componentType); + } else { + // No binding, do the normal way... + comp = ctx.getApplication().createComponent(componentType); + } + + // Parent the new component + if (parent != null) { + addChild(ctx, desc, parent, comp); + } + + // Return it... + return comp; + } + + /** + *

    This method returns the extraInfo that was set for this + * ComponentFactory from the + * {@link com.sun.jsftemplating.layout.descriptors.ComponentType}.

    + */ + public Serializable getExtraInfo() { + return _extraInfo; + } + + /** + *

    This method is invoked from the + * {@link com.sun.jsftemplating.layout.descriptors.ComponentType} to + * provide more information to the factory. For example, if the JSF + * component type was passed in, a single factory class could + * instatiate multiple components the extra info that is passed in.

    + * + *

    Some factory implementations may want to override this method to + * execute intialization code for the factory based in the value + * passed in.

    + */ + public void setExtraInfo(Serializable extraInfo) { + _extraInfo = extraInfo; + } + + /** + *

    Extra information associated with this ComponentFactory.

    + */ + private Serializable _extraInfo = null; + +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/EventComponentFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/EventComponentFactory.java new file mode 100644 index 0000000..6ed2c47 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/EventComponentFactory.java @@ -0,0 +1,68 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.basic; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an EventComponent + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "event".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("event") +public class EventComponentFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created EventComponent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + public static final String COMPONENT_TYPE = "com.sun.jsftemplating.EventComponent"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/ForEachFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/ForEachFactory.java new file mode 100644 index 0000000..09151fc --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/ForEachFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.basic; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an ForEach + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "foreach".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("foreach") +public class ForEachFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created ForEach. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.jsftemplating.ForEach"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/GenericFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/GenericFactory.java new file mode 100644 index 0000000..107f846 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/GenericFactory.java @@ -0,0 +1,100 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.basic; + +import java.io.Serializable; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is capable of creating any UIComponent that can be created + * via the Application.createComponent(componentType) + * method. It requires that the componentType property be + * set indicating what type of component should be instantiated.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "component".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("component") +public class GenericFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent. It requires that the "componentType" + * attribute be supplied with a valid JSF ComponentType. This may + * be supplied in the page on a per-use basis, or on an instance of + * this Factory via the + * {@link ComponentFactoryBase#setExtraInfo(Serializable)} + * method.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created UIComponent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Determine the componentType + String componentType = (String) descriptor.getEvaluatedOption(context, COMPONENT_TYPE, parent); + if (componentType == null) { + Serializable extraInfo = getExtraInfo(); + if (extraInfo != null) { + // This component allows the (default) CompnentType to be set + // on the factory. + componentType = extraInfo.toString(); + } else { + throw new IllegalArgumentException( + "\">component<\" requires a \"" + COMPONENT_TYPE + + "\" property to be set to the componentType of the " + + "component you wish to create."); + } + } + + // Create the UIComponent + UIComponent comp = createComponent(context, componentType, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    This the is the property name ("componentType") that will be used + * to define the componentType to be used to create the + * UIComponent. This much match the defined component + * type in the faces-config.xml file (this is usually stored along + * with the component .class files in the component's jar file).

    + */ + public static final String COMPONENT_TYPE = "componentType"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/IfFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/IfFactory.java new file mode 100644 index 0000000..51965d9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/IfFactory.java @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.basic; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an If + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "if".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("if") +public class IfFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created If. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // (re)set the "condition" property to avoid using an evaluated version + Object val = descriptor.getOption("condition"); + if (val != null) { + comp.getAttributes().put("condition", val); + } + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.jsftemplating.If"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/MessageFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/MessageFactory.java new file mode 100644 index 0000000..f2b6e2e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/MessageFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.basic; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIMessage; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a UIMessage + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "message".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("message") +public class MessageFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created UIMessage. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIMessage comp = new UIMessage(); + + // This needs to be done here (before setOptions) so that $...{...} + // expressions can be resolved... may want to defer these? + if (parent != null) { + addChild(context, descriptor, parent, comp); + } + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/StaticTextFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/StaticTextFactory.java new file mode 100644 index 0000000..34b3916 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/StaticTextFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.basic; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an StaticText + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "staticText".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("staticText") +public class StaticTextFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created StaticText. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.jsftemplating.StaticText"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/WhileFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/WhileFactory.java new file mode 100644 index 0000000..0b01cb8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/basic/WhileFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.basic; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an While + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "while".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("while") +public class WhileFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created While. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.jsftemplating.While"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/AjaxWrapperFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/AjaxWrapperFactory.java new file mode 100644 index 0000000..2dc3d48 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/AjaxWrapperFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.jmaki; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a jMaki + * AjaxWrapper UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "jmaki:ajax".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("jmaki:ajax") +public class AjaxWrapperFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created AjaxWrapper. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "AjaxWrapper"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/ExtensionFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/ExtensionFactory.java new file mode 100644 index 0000000..69f997e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/ExtensionFactory.java @@ -0,0 +1,76 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.jmaki; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a jMaki + * Extension UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "jmaki:extension".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("jmaki:extension") +public class ExtensionFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Extension. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // jMaki doesn't do this -- 3/4/2008 + comp.setRendererType("jmaki.ExtensionRenderer"); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "jmaki.Extension"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/PageFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/PageFactory.java new file mode 100644 index 0000000..4120f69 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/PageFactory.java @@ -0,0 +1,76 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.jmaki; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a jMaki + * Page UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "jmaki:page".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("jmaki:page") +public class PageFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Page. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // jMaki doesn't do this -- 3/4/2008 + comp.setRendererType("jmaki.PageRenderer"); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "jmaki.Page"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/ResourcesFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/ResourcesFactory.java new file mode 100644 index 0000000..1a44a32 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/ResourcesFactory.java @@ -0,0 +1,76 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.jmaki; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a jMaki + * Resources UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "jmaki:resources".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("jmaki:resources") +public class ResourcesFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Resources. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // jMaki doesn't do this -- 3/4/2008 + comp.setRendererType("jmaki.ResourcesRenderer"); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "jmaki.Resources"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/WidgetFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/WidgetFactory.java new file mode 100644 index 0000000..19772e1 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jmaki/WidgetFactory.java @@ -0,0 +1,76 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.jmaki; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a jMaki + * Widget UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "jmaki:widget".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("jmaki:widget") +public class WidgetFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Widget. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // jMaki doesn't do this -- 3/4/2008 + comp.setRendererType("jmaki.WidgetRenderer"); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "jmaki.Widget"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jsfext/AjaxZoneFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jsfext/AjaxZoneFactory.java new file mode 100644 index 0000000..2f801b7 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jsfext/AjaxZoneFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.jsfext; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an AjaxZone + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "jsfExt:ajaxZone".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("jsfExt:ajaxZone") +public class AjaxZoneFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating an + * AjaxZone UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created AjaxZone UIComponent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.faces.AjaxZone"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jsfext/ScriptsFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jsfext/ScriptsFactory.java new file mode 100644 index 0000000..2e3bf7a --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/jsfext/ScriptsFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.jsfext; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Scripts + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "jsfExt:scripts".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("jsfExt:scripts") +public class ScriptsFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Scripts UIComponent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.faces.extensions.avatar.Scripts"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/BodyFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/BodyFactory.java new file mode 100644 index 0000000..8745a04 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/BodyFactory.java @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Body + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:body".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:body") +public class BodyFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Body. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + comp.setRendererType(RENDERER_TYPE); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Output"; + + /** + *

    The default RendererType to set on the newly created component.

    + */ + public static final String RENDERER_TYPE = "javax.faces.Body"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ColumnFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ColumnFactory.java new file mode 100644 index 0000000..d042eb2 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ColumnFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Column + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:column".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:column") +public class ColumnFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Column. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Column"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/CommandButtonFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/CommandButtonFactory.java new file mode 100644 index 0000000..6f0b4dc --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/CommandButtonFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a CommandButton + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:commandButton".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:commandButton") +public class CommandButtonFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created CommandButton. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlCommandButton"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/CommandLinkFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/CommandLinkFactory.java new file mode 100644 index 0000000..292a86d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/CommandLinkFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a CommandLink + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:commandLink".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:commandLink") +public class CommandLinkFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created CommandLink. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlCommandLink"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/DataTableFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/DataTableFactory.java new file mode 100644 index 0000000..5ec4dad --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/DataTableFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a DataTable + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:dataTable".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:dataTable") +public class DataTableFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created DataTable. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlDataTable"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/FormFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/FormFactory.java new file mode 100644 index 0000000..1061498 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/FormFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Form + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:form".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:form") +public class FormFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Form. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Form"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/GraphicImageFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/GraphicImageFactory.java new file mode 100644 index 0000000..fafbce6 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/GraphicImageFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a GraphicImage + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:graphicImage".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:graphicImage") +public class GraphicImageFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created GraphicImage. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlGraphicImage"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/HeadFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/HeadFactory.java new file mode 100644 index 0000000..ffcf441 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/HeadFactory.java @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Head + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:head".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:head") +public class HeadFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Head component. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + comp.setRendererType(RENDERER_TYPE); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Output"; + + /** + *

    The default RendererType to set on the newly created component.

    + */ + public static final String RENDERER_TYPE = "javax.faces.Head"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputHiddenFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputHiddenFactory.java new file mode 100644 index 0000000..e779e21 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputHiddenFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a InputHidden + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:inputHidden".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:inputHidden") +public class InputHiddenFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created InputHidden. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlInputHidden"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputSecretFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputSecretFactory.java new file mode 100644 index 0000000..6a7af7e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputSecretFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a InputSecret + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:inputSecret".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:inputSecret") +public class InputSecretFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created InputSecret. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlInputSecret"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputTextFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputTextFactory.java new file mode 100644 index 0000000..03d431d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputTextFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a InputText + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:inputText".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:inputText") +public class InputTextFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created InputText. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlInputText"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputTextareaFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputTextareaFactory.java new file mode 100644 index 0000000..ff5f59d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/InputTextareaFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a InputTextarea + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:inputTextarea".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:inputTextarea") +public class InputTextareaFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created InputTextarea. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlInputTextarea"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/LoadBundleFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/LoadBundleFactory.java new file mode 100644 index 0000000..8f4db54 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/LoadBundleFactory.java @@ -0,0 +1,104 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.EventComponent; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition; + + +/** + *

    When using JSP as the view technology for JSF, you not only have + * components but also JSP tags that interact with JSF. In JSFTemplating + * the recommended approach to doing this is to use handlers. This + * offers a clean way to execute arbitrary Java code. While that is still + * the recommendation, this class is provided for added flexibility. The + * purpose of this class is to read a ResourceBundle and make it available + * to the page. The better approach would be to use the + * {@link com.sun.jsftemplating.handlers.ScopeHandlers#setResourceBundle} + * handler.

    + * + *

    The >f:loadBundle< tag does not represent a component, so this + * handler does not create a component, it returns the parent + * (which is passed in) after configuring the + * ResourceBundle.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "f:loadBundle". It requires a + * basename and a var property to be passed + * in. Optionally the locale can be passed in (this is not + * a feature of the JSF version, but an extra feature supported by the + * handler in JSFTemplating.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("f:loadBundle") +public class LoadBundleFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method loads a ResourceBundle.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor. + * @param parent The parent UIComponent (not used) + * + * @return parent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create an Event component for this + EventComponent event = new EventComponent(); + if (parent != null) { + addChild(context, descriptor, parent, event); + } + + // Get the inputs + String baseName = (String) descriptor.getEvaluatedOption(context, "basename", parent); + String var = (String) descriptor.getEvaluatedOption(context, "var", parent); + Locale locale = (Locale) descriptor.getEvaluatedOption(context, "locale", parent); + + // Create a handler (needed to execute code each time displayed)... + HandlerDefinition def = LayoutDefinitionManager. + getGlobalHandlerDefinition("setResourceBundle"); + Handler handler = new Handler(def); + handler.setInputValue("bundle", baseName); + handler.setInputValue("key", var); + handler.setInputValue("locale", locale); + List handlers = new ArrayList(); + handlers.add(handler); + event.getAttributes().put("beforeEncode", handlers); + + // Return (parent) + return event; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/MessageFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/MessageFactory.java new file mode 100644 index 0000000..41dfffc --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/MessageFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Message + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:message".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:message") +public class MessageFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Message. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Message"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/MessagesFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/MessagesFactory.java new file mode 100644 index 0000000..4aa2f00 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/MessagesFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Messages + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:messages".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:messages") +public class MessagesFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Messages. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Messages"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/NamingContainerFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/NamingContainerFactory.java new file mode 100644 index 0000000..c3c247f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/NamingContainerFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a NamingContainer + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "namingContainer".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("namingContainer") +public class NamingContainerFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created NamingContainer. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.NamingContainer"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputFormatFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputFormatFactory.java new file mode 100644 index 0000000..4e25c8c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputFormatFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a OutputFormat + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:outputFormat".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:outputFormat") +public class OutputFormatFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created OutputFormat. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlOutputFormat"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputLabelFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputLabelFactory.java new file mode 100644 index 0000000..31d7879 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputLabelFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a OutputLabel + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:outputLabel".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:outputLabel") +public class OutputLabelFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created OutputLabel. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlOutputLabel"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputLinkFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputLinkFactory.java new file mode 100644 index 0000000..833c2fe --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputLinkFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a OutputLink + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:outputLink".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:outputLink") +public class OutputLinkFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created OutputLink. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlOutputLink"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputScriptFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputScriptFactory.java new file mode 100644 index 0000000..367a64f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputScriptFactory.java @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a OutputScript + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:outputScript".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:outputScript") +public class OutputScriptFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created OutputScript. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + comp.setRendererType(RENDERER_TYPE); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Output"; + + /** + *

    The default RendererType to set on the newly created component.

    + */ + public static final String RENDERER_TYPE = "javax.faces.resource.Script"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputStylesheetFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputStylesheetFactory.java new file mode 100644 index 0000000..722ab4b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputStylesheetFactory.java @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a OutputStylesheet + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:outputStylesheet".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:outputStylesheet") +public class OutputStylesheetFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created OutputStylesheet. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + comp.setRendererType(RENDERER_TYPE); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.Output"; + + /** + *

    The default RendererType to set on the newly created component.

    + */ + public static final String RENDERER_TYPE = "javax.faces.resource.Stylesheet"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputTextFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputTextFactory.java new file mode 100644 index 0000000..bfd2201 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/OutputTextFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a OutputText + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:outputText".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:outputText") +public class OutputTextFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created OutputText. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlOutputText"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/PanelGridFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/PanelGridFactory.java new file mode 100644 index 0000000..640fb56 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/PanelGridFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a PanelGrid + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:panelGrid".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:panelGrid") +public class PanelGridFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created PanelGrid. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlPanelGrid"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/PanelGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/PanelGroupFactory.java new file mode 100644 index 0000000..970c080 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/PanelGroupFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a PanelGroup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:panelGroup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:panelGroup") +public class PanelGroupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created PanelGroup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlPanelGroup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ParamFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ParamFactory.java new file mode 100644 index 0000000..bd0e7ef --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ParamFactory.java @@ -0,0 +1,74 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a UIParameter + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "f:param".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("f:param") +public class ParamFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created UIParameter. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = + javax.faces.component.UIParameter.COMPONENT_TYPE; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectBooleanCheckboxFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectBooleanCheckboxFactory.java new file mode 100644 index 0000000..1821e4c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectBooleanCheckboxFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SelectBooleanCheckbox + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:selectBooleanCheckbox".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:selectBooleanCheckbox") +public class SelectBooleanCheckboxFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SelectBooleanCheckbox. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlSelectBooleanCheckbox"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectItemFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectItemFactory.java new file mode 100644 index 0000000..bfb57d2 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectItemFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a UISelectItem + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "f:selectItem".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("f:selectItem") +public class SelectItemFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created UISelectItem. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.SelectItem"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectItemsFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectItemsFactory.java new file mode 100644 index 0000000..3b103d8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectItemsFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a UISelectItems + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "f:selectItems".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("f:selectItems") +public class SelectItemsFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created UISelectItems. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.SelectItems"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyCheckboxFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyCheckboxFactory.java new file mode 100644 index 0000000..a3fc87d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyCheckboxFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SelectManyCheckbox + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:selectManyCheckbox".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:selectManyCheckbox") +public class SelectManyCheckboxFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SelectManyCheckbox. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlSelectManyCheckbox"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyListboxFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyListboxFactory.java new file mode 100644 index 0000000..bcaaeb9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyListboxFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SelectManyListbox + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:selectManyListbox".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:selectManyListbox") +public class SelectManyListboxFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SelectManyListbox. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.SelectManyListbox"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyMenuFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyMenuFactory.java new file mode 100644 index 0000000..894df5b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectManyMenuFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SelectManyMenu + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:selectManyMenu".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:selectManyMenu") +public class SelectManyMenuFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SelectManyMenu. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlSelectManyMenu"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneListboxFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneListboxFactory.java new file mode 100644 index 0000000..ec1c9c9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneListboxFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SelectOneListbox + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:selectOneListbox".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:selectOneListbox") +public class SelectOneListboxFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SelectOneListbox. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlSelectOneListbox"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneMenuFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneMenuFactory.java new file mode 100644 index 0000000..75746d5 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneMenuFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SelectOneMenu + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:selectOneMenu".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:selectOneMenu") +public class SelectOneMenuFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SelectOneMenu. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlSelectOneMenu"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneRadioFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneRadioFactory.java new file mode 100644 index 0000000..0e55c66 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/SelectOneRadioFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SelectOneRadio + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "h:selectOneRadio".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("h:selectOneRadio") +public class SelectOneRadioFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SelectOneRadio. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "javax.faces.HtmlSelectOneRadio"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ValidatorFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ValidatorFactory.java new file mode 100644 index 0000000..96b13f8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/ri/ValidatorFactory.java @@ -0,0 +1,114 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.ri; + +import javax.el.ELContext; +import javax.el.ValueExpression; +import javax.faces.application.Application; +import javax.faces.component.EditableValueHolder; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.validator.Validator; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.util.LogUtil; + + +/** + *

    This factory is responsible for instantiating a + * Validator and adding it to the parent. This factory + * does not create a UIComponent.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("f:validator") +public class ValidatorFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The parent UIComponent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + Object value = null; + Validator validator = null; + + // Check for the "binding" property + String binding = (String) descriptor.getOption("binding"); + if (binding != null) { + value = ComponentUtil.getInstance(context).resolveValue(context, descriptor, parent, binding); + if ((value != null) && !(value instanceof Validator)) { + // Warn developer that attempted to set a Validator that was + // not a Validator + if (LogUtil.warningEnabled()) { + LogUtil.warning("JSFT0009", (Object) parent.getId()); + } + } else { + validator = (Validator) value; + } + } + + // Check to see if we still need to create one... + if (validator == null) { + // Check for the "validatorId" property + String id = (String) descriptor.getOption("validatorId"); + if (id != null) { + id = (String) ComponentUtil.getInstance(context).resolveValue(context, descriptor, parent, id); + if (id != null) { + // Create a new Validator + Application app = context.getApplication(); + validator = app.createValidator(id); + if ((validator != null) && (binding != null)) { + // Set the validator on the binding, if bound + ELContext elctx = context.getELContext(); + ValueExpression ve = app.getExpressionFactory().createValueExpression(elctx, binding, Object.class); + ve.setValue(elctx, validator); + } + } + } + } + + // Set the validator on the parent... + if (validator != null) { + if (!(parent instanceof EditableValueHolder)) { + throw new IllegalArgumentException("You may only add " + + "f:validator tags to components which are " + + "EditableValueHolders. Component (" + parent.getId() + + ") is not an EditableValueHolder."); + } + ((EditableValueHolder) parent).addValidator(validator); + } + + // Return the validator + return parent; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AddRemoveFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AddRemoveFactory.java new file mode 100644 index 0000000..ae14546 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AddRemoveFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an AddRemove + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:addRemove".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:addRemove") +public class AddRemoveFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created AddRemove. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.AddRemove"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AjaxRequestFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AjaxRequestFactory.java new file mode 100644 index 0000000..e9fbe1f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AjaxRequestFactory.java @@ -0,0 +1,106 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Hyperlink + * UIComponent that is configured to submit an Ajax + * request.

    + * + *

    All properties are passed through to the underlying + * Hyperlink UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "ajaxRequest".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("ajaxRequest") +public class AjaxRequestFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent. You should specify the + * ajaxTarget for this component. See + * {@link #AJAX_TARGET}.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created AjaxRequest. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Setup the AjaxRequest Request +// FIXME: support javascript function to handle return value +// FIXME: support extra NVPs?? Maybe not needed? UIParameter instead? May be easier as a &n=v&... string. + String clientId = comp.getClientId(context); +// FIXME: XXX DEAL WITH THIS!!! +// FIXME: BUG: JSF automatically converts the '&' characters in attributes to & this causes a problem... talk to LH and JSF about this. +// String extraNVPs = "'&" + clientId + "_submittedField=" + clientId + "'"; + String extraNVPs = "'" + clientId + "_submittedField=" + clientId + "'"; + String jsHandlerFunction = "null"; +// FIXME: Support multiple targets? If I render multiple sections of the UIComponent tree and return a document describing the results... + String target = (String) descriptor.getEvaluatedOption(context, AJAX_TARGET, comp); + if ((target == null) || target.equals("")) { + target = clientId; + } + comp.getAttributes().put("onClick", "submitAjaxRequest('" + target + "', " +extraNVPs + ", " + jsHandlerFunction + "); return false;"); + + // Return the component + return comp; + } + + /** + *

    This is the property name that specifies the target for the + * Ajax request. If not specified, the link itself will be the target + * (which is likely not the desired target of the XMLHttpRequest). + * The target should be the clientId (i.e. the "id" you see in the + * HTML source) of the UIComponent.

    + * + *

    The property name is: ajaxTarget.

    + */ + public static final String AJAX_TARGET = "ajaxTarget"; + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Hyperlink"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlarmFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlarmFactory.java new file mode 100644 index 0000000..8b6081b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlarmFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Alarm + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:alarm".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:alarm") +public class AlarmFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Alarm. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Alarm"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlarmStatusFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlarmStatusFactory.java new file mode 100644 index 0000000..54f5134 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlarmStatusFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an AlarmStatus + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:alarmStatus".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:alarmStatus") +public class AlarmStatusFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created AlarmStatus. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.AlarmStatus"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlertFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlertFactory.java new file mode 100644 index 0000000..2d650bc --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AlertFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Alert + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:alert".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:alert") +public class AlertFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Alert. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Alert"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AnchorFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AnchorFactory.java new file mode 100644 index 0000000..f7fd12b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/AnchorFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Anchor + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:anchor".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:anchor") +public class AnchorFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Anchor. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Anchor"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/BodyFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/BodyFactory.java new file mode 100644 index 0000000..73de235 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/BodyFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Body + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:body".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:body") +public class BodyFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Body. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Body"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/BreadcrumbsFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/BreadcrumbsFactory.java new file mode 100644 index 0000000..0229389 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/BreadcrumbsFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Breadcrumbs + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:breadcrumbs".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:breadcrumbs") +public class BreadcrumbsFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Breadcrumbs. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Breadcrumbs"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ButtonFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ButtonFactory.java new file mode 100755 index 0000000..736e14f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ButtonFactory.java @@ -0,0 +1,82 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Button + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:button".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:button") +public class ButtonFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Button. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Default to primary button + if (descriptor.getOption("primary") == null) { + // Use ValueBinding vs. property so we don't set the local value + // flag which will hide any future VB that is set on the component + comp.setValueBinding("primary", + context.getApplication().createValueBinding("#{true}")); + } + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the value + return comp; + + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Button"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CalendarFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CalendarFactory.java new file mode 100644 index 0000000..9b621a4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CalendarFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Calendar + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:calendar".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:calendar") +public class CalendarFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Calendar. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Calendar"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CheckboxFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CheckboxFactory.java new file mode 100644 index 0000000..3dd8a22 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CheckboxFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Checkbox + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:checkbox".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:checkbox") +public class CheckboxFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Checkbox. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Checkbox"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CheckboxGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CheckboxGroupFactory.java new file mode 100644 index 0000000..81b1213 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CheckboxGroupFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a CheckboxGroup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:checkboxGroup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:checkboxGroup") +public class CheckboxGroupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created CheckboxGroup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.CheckboxGroup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ColoredTextFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ColoredTextFactory.java new file mode 100644 index 0000000..d4fd8a5 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ColoredTextFactory.java @@ -0,0 +1,85 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a StaticText + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:coloredText".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:coloredText") +public class ColoredTextFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created StaticText. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set escape as false by default, don't call setEscape() b/c then + // ValueExpressions won't get evaluated + if (!descriptor.getOptions().containsKey("escape")) { + setOption(context, comp, descriptor, "escape", "#{false}"); + } + + // Set the color + String color = (String) descriptor.getEvaluatedOption(context, "color", comp); + if (color != null) { + comp.getAttributes().put("style", "color: " + color + ";"); + } + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.StaticText"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTaskFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTaskFactory.java new file mode 100644 index 0000000..22529aa --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTaskFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an CommonTask + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:commonTask".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:commonTask") +public class CommonTaskFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created CommonTask. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.CommonTask"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTasksGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTasksGroupFactory.java new file mode 100644 index 0000000..b72b925 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTasksGroupFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an CommonTasksGroup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:commonTasksGroup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:commonTasksGroup") +public class CommonTasksGroupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created CommonTasksGroup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.CommonTasksGroup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTasksSectionFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTasksSectionFactory.java new file mode 100644 index 0000000..bbb328f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/CommonTasksSectionFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an CommonTasksSection + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:commonTasksSection".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:commonTasksSection") +public class CommonTasksSectionFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created CommonTasksSection. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.CommonTasksSection"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/DropDownFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/DropDownFactory.java new file mode 100644 index 0000000..9af8117 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/DropDownFactory.java @@ -0,0 +1,145 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.util.Util; + + +// FIXME: Document +/** + *

    This factory is responsible for instantiating a DropDrown + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:dropDown".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:dropDown") +public class DropDownFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created DropDown. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, getComponentType(), descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Check to see if the user is passing in Lists to be converted to a + // List of Option objects for the "items" property. + ComponentUtil compUtil = ComponentUtil.getInstance(context); + Object labels = compUtil.resolveValue( + context, descriptor, comp, descriptor.getOption("labels")); + if (labels != null) { + List optionList = new ArrayList(); + Object values = compUtil.resolveValue( + context, descriptor, comp, descriptor.getOption("values")); + if (values == null) { + values = labels; + } + + try { + // Use reflection (for now) to avoid a build dependency + // Find the Option constuctor... + Constructor optConst = Util.loadClass( + "com.sun.webui.jsf.model.Option", this). + getConstructor(Object.class, String.class); + + if (values instanceof List) { + // We have a List, we need to convert to Option objects. + Iterator it = ((List) labels).iterator(); + for (Object obj : (List) values) { + optionList.add( + optConst.newInstance(obj, it.next().toString())); + } + } else if (values instanceof Object[]) { + Object [] valArr = (Object []) values; + Object [] labArr = (Object []) labels; + int len = valArr.length; + // Convert the array to Option objects + for (int count = 0; count < len; count++) { + optionList.add( + optConst.newInstance( + valArr[count], labArr[count].toString())); + } + } + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } catch (NoSuchMethodException ex) { + ex.printStackTrace(); + } catch (InstantiationException ex) { + ex.printStackTrace(); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + } + + // Set the options + comp.getAttributes().put("items", optionList); + } + + // Return the component + return comp; + } + + /** + *

    This method returns the ComponentType of this component. It is + * implemented this way to allow subclasses to easily provide a + * different ComponentType.

    + */ + protected String getComponentType() { + return COMPONENT_TYPE; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.DropDown"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/DynamicColumnTableRowGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/DynamicColumnTableRowGroupFactory.java new file mode 100644 index 0000000..eb99209 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/DynamicColumnTableRowGroupFactory.java @@ -0,0 +1,226 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import java.util.ArrayList; +import java.util.List; + +import javax.el.ValueExpression; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutStaticText; +import com.sun.jsftemplating.layout.event.CreateChildEvent; + + +/** + *

    This factory is responsible for instantiating a TableRowGroup + * UIComponent which supports a dynamic # of columns.

    + * + *

    The {@link ComponentType} id for this factory is: + * "sun:dynamicColumnRowGroup".

    + * + *

    This factory fires a "createChild" event for each column that it + * creates. This allows the children of the column to be created in the + * event allowing for the page developer to customize this (otherwise + * only "StaticText" children will be created in the columns). In the + * "createChild" event handler, you may return a UIComponent + * which will be used as the UIComponent for that column. + * You also have access to the column UICompoent and may add + * children directly to it if you wish. The "data" value set in the + * CreateChildEvent object is the value passed in for the + * column.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:dynamicColumnRowGroup") +public class DynamicColumnTableRowGroupFactory extends TableRowGroupFactory { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param ctx The FacesContext + * @param desc The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TableRowGroup. + */ + public UIComponent create(FacesContext ctx, LayoutComponent desc, UIComponent parent) { + // Create the UIComponent + UIComponent comp = super.create(ctx, desc, parent); + String id = comp.getId(); + + // Dynamically create the child columns... + // First find all the column-specific properties + ArrayList colAttKeys = new ArrayList(); + for (String key : desc.getOptions().keySet()) { + if (key.startsWith("column")) { + colAttKeys.add(key); + } + } + + // Make sure we have some... + if (colAttKeys.size() == 0) { + // Nothing to do... hopefully there are table column children, + // otherwise nothing will happen + return comp; + } + + // Now determine the # of columns + List values = getColumnPropertyValues( + ctx, desc, colAttKeys.get(0), parent); + int size = values.size(); + + // Create the LC's for the columns + List columns = new ArrayList(size); + ComponentType colType = + LayoutDefinitionManager.getGlobalComponentType(ctx, COLUMN_TYPE); + for (int idx = 0; idx < size; idx++) { + LayoutComponent column = new LayoutComponent( + desc, id + COLUMN_SEPERATOR + idx, colType); + columns.add(column); + } + + // Loop through the properties to set on the columns + for (String key : colAttKeys) { + if (key.equals(COLUMN_VALUE_KEY)) { + // Skip the value as it is added as a child. + continue; + } + values = getColumnPropertyValues(ctx, desc, key, parent); + + // Loop through the columns + int idx = 0; + for (Object entry : values) { + // Set the value of each property on each column + columns.get(idx++).addOption(getColumnKey(key), entry); + } + } + + // Create the columns... + UIComponent columnComp = null; + String value = null; + Object eventVal = null; + values = getColumnPropertyValues(ctx, desc, COLUMN_VALUE_KEY, parent); + int idx = 0; + ComponentUtil compUtil = ComponentUtil.getInstance(ctx); + for (LayoutComponent columnDesc : columns) { + columnComp = compUtil.createChildComponent( + ctx, columnDesc, comp); + + value = "" + values.get(idx++); + eventVal = desc.dispatchHandlers(ctx, + CreateChildEvent.EVENT_TYPE, + new CreateChildEvent(columnComp, value)); + + if ((eventVal != null) && (eventVal instanceof UIComponent)) { + // Add the child created during the event. + columnComp.getChildren().add((UIComponent) eventVal); + } else { + // Create the column (value) child + // The child of each TableColumn will be a LayoutStaticText for now... + compUtil.createChildComponent(ctx, + new LayoutStaticText(columnDesc, + columnDesc.getUnevaluatedId() + CHILD_SUFFIX, value), + columnComp); + } + } + + // Return the component + return comp; + } + + /** + *

    This method obtains a List from the given + * property name. If the value is not a List, + * it will throw an exception.

    + */ + private List getColumnPropertyValues(FacesContext ctx, LayoutComponent parentDesc, String propertyName, UIComponent parent) { + Object val = parentDesc.getEvaluatedOption(ctx, propertyName, parent); + if (val == null) { + throw new IllegalArgumentException( + "DynamicColumnTableRowGroupFactory requires a valid '" + + propertyName + "' attribute, however one was not supplied!"); + } + if (val instanceof String) { + // Only try to do this if we have a String (not for Lists) + if (ComponentUtil.getInstance(ctx).isValueReference((String) val)) { +// FIXME: resolve $x{y} values: Object newBinding = VariableResolver.resolveVariables(ctx, elt, parent, binding);?? +// FIXME: I believe I have a util method for this (resolveValue?) + ValueExpression ve = + ctx.getApplication().getExpressionFactory(). + createValueExpression(ctx.getELContext(), + (String) val, Object.class); + val = ve.getValue(ctx.getELContext()); + } + } + if (!(val instanceof List)) { + throw new IllegalArgumentException( + "DynamicColumnTableRowGroupFactory requires all 'column*' " + + "properties to resolve to an instance of a List. '" + + propertyName + "' is a '" + val.getClass().getName() + + "'!"); + } + + // Return the result + return (List) val; + } + + /** + *

    This method removes the "column" prefix and lower-cases the first + * letter of the property name.

    + */ + private String getColumnKey(String key) { + return key.substring(COLUMN_LEN, COLUMN_LEN + 1).toLowerCase() + + key.substring(COLUMN_LEN + 1); + } + + /** + *

    This method is overriden to prevent setting properties that don't + * apply to this component (but may apply to their children or to + * the behavior of this factory).

    + */ + protected void setOption(FacesContext ctx, UIComponent comp, LayoutComponent desc, String key, Object value) { + if (key.startsWith("column")) { + return; + } + super.setOption(ctx, comp, desc, key, value); + } + + + /** + *

    The component type of the column component to create.

    + */ + public static final String COLUMN_TYPE = "sun:tableColumn"; + public static final String COLUMN_VALUE_KEY= "columnValue"; + public static final String COLUMN_SEPERATOR= "col"; + public static final String CHILD_SUFFIX = "child"; + public static final int COLUMN_LEN = "column".length(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/EditableListFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/EditableListFactory.java new file mode 100644 index 0000000..c054395 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/EditableListFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an EditableList + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:editableList".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:editableList") +public class EditableListFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created EditableList. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.EditableList"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FieldFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FieldFactory.java new file mode 100755 index 0000000..82b3635 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FieldFactory.java @@ -0,0 +1,75 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a radio button + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:field"

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:field") +public class FieldFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext. + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent. + * + * @return The newly created TextField. + */ + public UIComponent create(FacesContext context, + LayoutComponent descriptor, + UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the value + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Field"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FileChooserFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FileChooserFactory.java new file mode 100644 index 0000000..e62f225 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FileChooserFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a FileChooser + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:fileChooser".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:fileChooser") +public class FileChooserFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created FileChooser. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.FileChooser"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FooterFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FooterFactory.java new file mode 100644 index 0000000..eb92983 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FooterFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Footer + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:footer".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:footer") +public class FooterFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Footer. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Footer"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FormFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FormFactory.java new file mode 100644 index 0000000..f9909d3 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FormFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Form + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:form".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:form") +public class FormFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Form. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Form"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FrameFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FrameFactory.java new file mode 100644 index 0000000..89655ad --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FrameFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Frame + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:frame".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:frame") +public class FrameFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Frame. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Frame"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FrameSetFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FrameSetFactory.java new file mode 100644 index 0000000..0d5dc5d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/FrameSetFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an FrameSet + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:frameSet".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:frameSet") +public class FrameSetFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created FrameSet. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.FrameSet"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HeadFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HeadFactory.java new file mode 100644 index 0000000..cb353e0 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HeadFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Head + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:head".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:head") +public class HeadFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created HelpInline. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Head"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HelpInlineFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HelpInlineFactory.java new file mode 100644 index 0000000..f7d138c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HelpInlineFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a HelpInline + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:helpInline".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:helpInline") +public class HelpInlineFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created HelpInline. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.HelpInline"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HelpWindowFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HelpWindowFactory.java new file mode 100644 index 0000000..15bda80 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HelpWindowFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a HelpWindow + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:helpWindow".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:helpWindow") +public class HelpWindowFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created HelpWindow. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.HelpWindow"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HiddenFieldFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HiddenFieldFactory.java new file mode 100644 index 0000000..09d778d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HiddenFieldFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a HiddenField + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:hidden".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:hidden") +public class HiddenFieldFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created HiddenField. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.HiddenField"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HtmlFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HtmlFactory.java new file mode 100644 index 0000000..78207ee --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HtmlFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Html + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:html".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:html") +public class HtmlFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Html. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Html"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HyperlinkFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HyperlinkFactory.java new file mode 100644 index 0000000..4eb0f1d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/HyperlinkFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Hyperlink + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:hyperlink".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:hyperlink") +public class HyperlinkFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Hyperlink. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Hyperlink"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IFrameFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IFrameFactory.java new file mode 100644 index 0000000..2a44874 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IFrameFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an IFrame + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:iframe".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:iframe") +public class IFrameFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created IFrame. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.IFrame"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IconFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IconFactory.java new file mode 100644 index 0000000..c7781c6 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IconFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Icon + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:icon"

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:icon") +public class IconFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Icon. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Icon"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IconHyperlinkFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IconHyperlinkFactory.java new file mode 100644 index 0000000..8649502 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/IconHyperlinkFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an IconHyperlink + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:iconHyperlink".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:iconHyperlink") +public class IconHyperlinkFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created IconHyperlink. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.IconHyperlink"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ImageComponentFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ImageComponentFactory.java new file mode 100644 index 0000000..5fdc301 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ImageComponentFactory.java @@ -0,0 +1,77 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for creating a ImageComponent + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:image".

    + * + * @author Rick Ratta + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:image") +public class ImageComponentFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * ImageComponent UIComponent.

    + * + * @param context The FacesContext + * + * @param descriptor The {@link LayoutComponent} descriptor that is + * associated with the requested + * ImageComponent. + * + * @param parent The parent UIComponent + * + * @return The newly created ImageComponent. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties (allow these to override theme) + setOptions(context, descriptor, comp); + + // Return the value + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Image"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ImageHyperlinkFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ImageHyperlinkFactory.java new file mode 100644 index 0000000..4784ac8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ImageHyperlinkFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an ImageHyperlink + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:imageHyperlink".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:imageHyperlink") +public class ImageHyperlinkFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created ImageHyperlink. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.ImageHyperlink"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/JobStatusFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/JobStatusFactory.java new file mode 100644 index 0000000..1b830b4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/JobStatusFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a JobStatus + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:jobStatus".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:jobStatus") +public class JobStatusFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created JobStatus. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.JobStatus"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LabelFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LabelFactory.java new file mode 100644 index 0000000..798f09c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LabelFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for creating a Label + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:label".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:label") +public class LabelFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Label. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the value + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Label"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LegendFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LegendFactory.java new file mode 100644 index 0000000..00ae642 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LegendFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Legend + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:legend".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:legend") +public class LegendFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Legend. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Legend"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LinkFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LinkFactory.java new file mode 100644 index 0000000..8756088 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/LinkFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Link + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:link".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:link") +public class LinkFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Link. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Link"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ListboxFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ListboxFactory.java new file mode 100644 index 0000000..2a79802 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ListboxFactory.java @@ -0,0 +1,55 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import com.sun.jsftemplating.annotation.UIComponentFactory; + +// FIXME: Document + +/** + *

    This factory is responsible for instantiating an Listbox + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:listbox".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:listbox") +public class ListboxFactory extends DropDownFactory { + + /** + *

    This method overrides the parent class to return a different + * ComponentType.

    + */ + protected String getComponentType() { + return COMPONENT_TYPE; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Listbox"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MarkupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MarkupFactory.java new file mode 100644 index 0000000..1257ce2 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MarkupFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Markup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:markup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:markup") +public class MarkupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Markup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Markup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MastheadFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MastheadFactory.java new file mode 100644 index 0000000..8b3a761 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MastheadFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Masthead + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:masthead".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:masthead") +public class MastheadFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Masthead. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Masthead"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MessageFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MessageFactory.java new file mode 100644 index 0000000..2d6a175 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MessageFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Message + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:message".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:message") +public class MessageFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Message. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Message"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MessageGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MessageGroupFactory.java new file mode 100644 index 0000000..906e0d4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MessageGroupFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an MessageGroup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:messageGroup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:messageGroup") +public class MessageGroupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created MessageGroup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.MessageGroup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MetaFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MetaFactory.java new file mode 100644 index 0000000..df3b9f9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/MetaFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Meta + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:meta".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:meta") +public class MetaFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Meta. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Meta"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/NotificationPhraseFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/NotificationPhraseFactory.java new file mode 100644 index 0000000..3a262d6 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/NotificationPhraseFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a NotificationPhrase + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:notificationPhrase".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:notificationPhrase") +public class NotificationPhraseFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created NotificationPhrase. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.NotificationPhrase"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/OrderableListFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/OrderableListFactory.java new file mode 100644 index 0000000..7aab54f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/OrderableListFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an OrderableList + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:orderableList".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:orderableList") +public class OrderableListFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created OrderableList. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.OrderableList"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageAlertFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageAlertFactory.java new file mode 100644 index 0000000..5f6cc27 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageAlertFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a PageAlert + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:pageAlert".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:pageAlert") +public class PageAlertFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created PageAlert. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.PageAlert"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageFactory.java new file mode 100644 index 0000000..c4b74a1 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Page + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:page".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:page") +public class PageFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Page. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Page"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageSeparatorFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageSeparatorFactory.java new file mode 100644 index 0000000..058ec59 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PageSeparatorFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a PageSeparator + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:pageSeparator".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:pageSeparator") +public class PageSeparatorFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created PageSeparator. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.PageSeparator"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PanelGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PanelGroupFactory.java new file mode 100644 index 0000000..5135fe8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PanelGroupFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a PanelGroup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:panelGroup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:panelGroup") +public class PanelGroupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created PanelGroup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.PanelGroup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PasswordFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PasswordFactory.java new file mode 100755 index 0000000..8a11b9f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PasswordFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a radio button + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:password".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:passwordField") +public class PasswordFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext. + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent. + * + * @return The newly created PasswordField. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the value + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.PasswordField"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertyFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertyFactory.java new file mode 100644 index 0000000..550186b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertyFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Property + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:property".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:property") +public class PropertyFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Property. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Property"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertySheetFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertySheetFactory.java new file mode 100644 index 0000000..11bc4ea --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertySheetFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a PropertySheet + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:propertySheet".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:propertySheet") +public class PropertySheetFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created PropertySheet. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.PropertySheet"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertySheetSectionFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertySheetSectionFactory.java new file mode 100644 index 0000000..3e142a4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/PropertySheetSectionFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a + * PropertySheetSection UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:propertySheetSection".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:propertySheetSection") +public class PropertySheetSectionFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created PropertySheetSection. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.PropertySheetSection"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/RadioButtonFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/RadioButtonFactory.java new file mode 100644 index 0000000..4e853aa --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/RadioButtonFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a RadioButton + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:radioButton".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:radioButton") +public class RadioButtonFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created RadioButton. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.RadioButton"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/RadioButtonGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/RadioButtonGroupFactory.java new file mode 100644 index 0000000..3d26e62 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/RadioButtonGroupFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a RadioButtonGroup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:radioButtonGroup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:radioButtonGroup") +public class RadioButtonGroupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created RadioButtonGroup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.RadioButtonGroup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/SchedulerFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/SchedulerFactory.java new file mode 100644 index 0000000..3b3771b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/SchedulerFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating an Scheduler + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:scheduler".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:scheduler") +public class SchedulerFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Scheduler. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Scheduler"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ScriptFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ScriptFactory.java new file mode 100644 index 0000000..2f4f0e2 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ScriptFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Script + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:script".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:script") +public class ScriptFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Script. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Script"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/SkipHyperlinkFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/SkipHyperlinkFactory.java new file mode 100644 index 0000000..a04464b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/SkipHyperlinkFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a SkipHyperlink + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:skipHyperlink".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:skipHyperlink") +public class SkipHyperlinkFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created SkipHyperlink. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.SkipHyperlink"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/StaticTextFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/StaticTextFactory.java new file mode 100644 index 0000000..9ec4da3 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/StaticTextFactory.java @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a StaticText + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:staticText".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:staticText") +public class StaticTextFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created StaticText. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set escape as false by default, don't call setEscape() b/c then + // ValueExpressions won't get evaluated + if (!descriptor.getOptions().containsKey("escape")) { + setOption(context, comp, descriptor, "escape", "#{false}"); + } + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.StaticText"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TabFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TabFactory.java new file mode 100644 index 0000000..c5429c1 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TabFactory.java @@ -0,0 +1,81 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Tab + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tab".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tab") +public class TabFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Tab. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + /* + String actionString = (String) descriptor.getOption("actionString"); + if (null != actionString) { +// FIXME: Add back when we have a ConstantMethodBinding class to use +// comp.setAction(new ConstantMethodBinding(actionString)); + } + */ + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Tab"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TabSetFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TabSetFactory.java new file mode 100644 index 0000000..d5e9c59 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TabSetFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TabSet + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tabSet".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tabSet") +public class TabSetFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TabSet. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TabSet"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableActionsFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableActionsFactory.java new file mode 100644 index 0000000..cdbb06c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableActionsFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TableActions + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tableActions".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tableActions") +public class TableActionsFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TableActions. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TableActions"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableColumnFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableColumnFactory.java new file mode 100644 index 0000000..6267cb3 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableColumnFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TableColumn + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tableColumn".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tableColumn") +public class TableColumnFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TableColumn. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TableColumn"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableFactory.java new file mode 100644 index 0000000..c31e208 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Table + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:table".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:table") +public class TableFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Table. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Table"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableFooterFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableFooterFactory.java new file mode 100644 index 0000000..197c4fa --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableFooterFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TableFooter + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tableFooter".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tableFooter") +public class TableFooterFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TableFooter. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TableFooter"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableHeaderFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableHeaderFactory.java new file mode 100644 index 0000000..56b1362 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableHeaderFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TableHeader + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tableHeader".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tableHeader") +public class TableHeaderFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TableHeader. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TableHeader"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TablePanelsFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TablePanelsFactory.java new file mode 100644 index 0000000..f493245 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TablePanelsFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TablePanels + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tablePanels".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tablePanels") +public class TablePanelsFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TablePanels. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TablePanels"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableRowGroupFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableRowGroupFactory.java new file mode 100644 index 0000000..9787bb8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TableRowGroupFactory.java @@ -0,0 +1,122 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.component.dataprovider.MultipleListDataProvider; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.util.LogUtil; + + +/** + *

    This factory is responsible for instantiating a TableRowGroup + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tableRowGroup".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tableRowGroup") +public class TableRowGroupFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TableRowGroup. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Handle "data" option specially... + ComponentUtil compUtil = ComponentUtil.getInstance(context); + Object data = compUtil.resolveValue( + context, descriptor, comp, descriptor.getOption("data")); + if (data != null) { + // Create a DataProvider + if (!(data instanceof List)) { + throw new IllegalArgumentException("TableRowGroupFactory " + + "only supports values of type \"java.util.List\" " + + "for the 'data' attribute."); + } + if ((((List) data).size() > 0) && + !(((List) data).get(0) instanceof List)) { + Object obj = ((List) data).get(0); + if (obj == null) { + // In this case, treat this as an empty List and log a + // warning... this prevents some cases from blowing up + // just b/c there is no data. + if (LogUtil.configEnabled()) { + LogUtil.config("JSFT0008"); + } + ((List) data).set(0, new ArrayList()); + } else { + obj = obj.getClass().getName(); + // We don't have a List of List of Object! + throw new IllegalArgumentException("TableRowGroupFactory " + + "expects a List>. Where the outer " + + "List should be a List of sources, and the inner" + + " List should be a List of rows. However, the " + + "following was passed in: List<" + obj + ">."); + } + } + List> lists = (List>) data; + Object dataProvider = new MultipleListDataProvider(lists); + + // Remove the data object from the UIComponent, not needed + Map atts = comp.getAttributes(); + atts.remove("data"); +// FIXME: This stores the *data* in the UIComponent... change to use a #{} value binding to push the data somewhere else. Session?? Configurable? + atts.put("sourceData", dataProvider); + } + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TableRowGroup"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TextAreaFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TextAreaFactory.java new file mode 100644 index 0000000..d4f003f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TextAreaFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TextArea + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:textArea".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:textArea") +public class TextAreaFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TextArea. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TextArea"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TextFieldFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TextFieldFactory.java new file mode 100644 index 0000000..3bea92f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TextFieldFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TextField + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:textField".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:textField") +public class TextFieldFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TextField. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TextField"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ThemeLinksFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ThemeLinksFactory.java new file mode 100644 index 0000000..1b1d282 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/ThemeLinksFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a ThemeLinks + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:themeLinks".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:themeLinks") +public class ThemeLinksFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created ThemeLinks. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.ThemeLinks"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TimeStampFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TimeStampFactory.java new file mode 100644 index 0000000..6abf909 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TimeStampFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TimeStamp + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:timeStamp".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:timeStamp") +public class TimeStampFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TimeStamp. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TimeStamp"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TitleFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TitleFactory.java new file mode 100644 index 0000000..9db1e4c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TitleFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a ContentPageTitle + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:title".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:title") +public class TitleFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created ContentPageTitle. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.ContentPageTitle"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TreeFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TreeFactory.java new file mode 100644 index 0000000..1fffda6 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TreeFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Tree + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:tree".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:tree") +public class TreeFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Tree. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Tree"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TreeNodeFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TreeNodeFactory.java new file mode 100644 index 0000000..c0685ee --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/TreeNodeFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a TreeNode + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:treeNode".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:treeNode") +public class TreeNodeFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created TreeNode. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.TreeNode"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/UploadFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/UploadFactory.java new file mode 100644 index 0000000..d0194e8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/UploadFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Upload + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:upload".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:upload") +public class UploadFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Upload. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Upload"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/VersionPageFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/VersionPageFactory.java new file mode 100644 index 0000000..6989c40 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/VersionPageFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a VersionPage + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:versionPage".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:versionPage") +public class VersionPageFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created VersionPage. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.VersionPage"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardBranchFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardBranchFactory.java new file mode 100644 index 0000000..2a95bee --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardBranchFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a WizardBranch + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:wizardBranch".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:wizardBranch") +public class WizardBranchFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created WizardBranch. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.WizardBranch"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardBranchStepsFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardBranchStepsFactory.java new file mode 100644 index 0000000..0fef7b9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardBranchStepsFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a WizardBranchSteps + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:wizardBranchSteps".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:wizardBranchSteps") +public class WizardBranchStepsFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created WizardBranchSteps. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.WizardBranchSteps"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardFactory.java new file mode 100644 index 0000000..8633d42 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a Wizard + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:wizard".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:wizard") +public class WizardFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created Wizard. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.Wizard"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardStepFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardStepFactory.java new file mode 100644 index 0000000..d8b5132 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardStepFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a WizardStep + * UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:wizardStep".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:wizardStep") +public class WizardStepFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created WizardStep. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.WizardStep"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardSubstepBranchFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardSubstepBranchFactory.java new file mode 100644 index 0000000..0fe8aaf --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/sun/WizardSubstepBranchFactory.java @@ -0,0 +1,73 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.sun; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; + + +/** + *

    This factory is responsible for instantiating a + * WizardSubstepBranch UIComponent.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "sun:wizardSubstepBranch".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("sun:wizardSubstepBranch") +public class WizardSubstepBranchFactory extends ComponentFactoryBase { + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created WizardSubstepBranch. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Create the UIComponent + UIComponent comp = createComponent(context, COMPONENT_TYPE, descriptor, parent); + + // Set all the attributes / properties + setOptions(context, descriptor, comp); + + // Return the component + return comp; + } + + /** + *

    The UIComponent type that must be registered in the + * faces-config.xml file mapping to the UIComponent class + * to use for this UIComponent.

    + */ + public static final String COMPONENT_TYPE = "com.sun.webui.jsf.WizardSubstepBranch"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/DynamicTreeNodeFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/DynamicTreeNodeFactory.java new file mode 100644 index 0000000..0b97f88 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/DynamicTreeNodeFactory.java @@ -0,0 +1,241 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.tree; + +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.UIComponentFactory; +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.component.factory.ComponentFactoryBase; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.util.Util; + + +/** + *

    Portions of many trees are non-static, or Dynamic. By this it is meant + * that some of the nodes can only be determined at Runtime. The goal of + * this factory is to provide a means for dynamic tree nodes to be + * defined. This implementation allows a portion or an entire tree to be + * defined.

    + * + *

    It relies on the supplied {@link TreeAdaptor} to drive the creation + * of the "root" tree node. The "root" node is a single Tree or TreeNode + * that is returned from the {@link #create(FacesContext, LayoutComponent, + * UIComponent)} method. Since this is a factory class for creating a + * single UIComponent, it is expected that a single UIComponent is + * returned from this method. However, the returned UIComponent may + * contain 0 or more children (other TreeNodes). The {@link TreeAdaptor} + * facilitates this.

    + * + *

    The {@link TreeAdaptor} implemenation is respsonsible for traversing + * the tree data and providing the necessary information about that data + * to this factory. The tree data can be stored in any format, a specific + * TreeAdaptor must be written to interpret each unique type of data + * format. When this factory interacts with the {@link TreeAdaptor}, it + * passes an Object that represents a tree node in the + * arbitrary data format. This Object is obtained originally + * from the {@link TreeAdaptor}, so the developer has control over what + * object is used to identify tree nodes in their own data format.

    + * + *

    See {@link TreeAdaptor} to see the necessary methods to implement in + * order for this factory to be capable of populating + * TreeNodes based on your data.

    + * + *

    The {@link com.sun.jsftemplating.layout.descriptors.ComponentType} + * id for this factory is: "dynamicTreeNode".

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@UIComponentFactory("dynamicTreeNode") +public class DynamicTreeNodeFactory extends ComponentFactoryBase { + + /** + * Constructor + */ + public DynamicTreeNodeFactory() { + } + + + /** + *

    This is the factory method responsible for creating the + * UIComponent.

    + * + * @param context The FacesContext + * @param descriptor The {@link LayoutComponent} descriptor associated + * with the requested UIComponent. + * @param parent The parent UIComponent + * + * @return The newly created component. + */ + public UIComponent create(FacesContext context, LayoutComponent descriptor, UIComponent parent) { + // Get the TreeAdaptor which should be used + TreeAdaptor treeAdaptor = getTreeAdaptor(context, descriptor, parent); + + // Initialize the TreeAdaptor instance + treeAdaptor.init(); + + // First pull off the root... + Object currentObj = treeAdaptor.getTreeNodeObject(); + + // Return the root TreeNode + return processNode(context, treeAdaptor, currentObj, parent); + } + + /** + *

    This method gets the TreeAdaptor by looking at the + * {@link #TREE_ADAPTOR_CLASS} option and invoking + * getInstance on the specified TreeAdaptor + * implementation.

    + */ + protected TreeAdaptor getTreeAdaptor(FacesContext ctx, LayoutComponent desc, UIComponent parent) { + TreeAdaptor adaptor = null; + Object cls = desc.getEvaluatedOption(ctx, TREE_ADAPTOR_CLASS, parent); + if (cls == null) { + throw new IllegalArgumentException("'" + TREE_ADAPTOR_CLASS + + "' must be specified!"); + } + try { + Class adaptorClass = Util.getClass(cls); + adaptor = (TreeAdaptor) adaptorClass.getMethod("getInstance", + (Class []) new Class[] {FacesContext.class, + LayoutComponent.class, UIComponent.class}). + invoke((Object) null, + (Object []) new Object[] {ctx, + desc, parent}); + } catch (ClassNotFoundException ex) { + throw new RuntimeException(ex); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } catch (InvocationTargetException ex) { + throw new RuntimeException(ex); + } + + // Return the TreeAdaptor + return adaptor; + } + + /** + *

    This method is responsible for creating and configuring a + * TreeNode given its TreeNode object. It + * then recurses for each child TreeNode object.

    + */ + protected UIComponent processNode(FacesContext ctx, TreeAdaptor adaptor, Object currentObj, UIComponent parent) { + // Pull off the important information... + String id = adaptor.getId(currentObj); + String factoryClass = adaptor.getFactoryClass(currentObj); + // NOTE: Properties specify things such as: + // URL, Text, Image, Action, Expanded, ActionListener, etc. + Map props = adaptor.getFactoryOptions(currentObj); + Properties properties = Util.mapToProperties(props); + + // Create TreeNode + UIComponent node = ComponentUtil.getInstance(ctx).getChild( + (UIComponent) parent, id, factoryClass, properties); + + // The above util method defaults to using a facet... change to child + // NOTE: The above needs "parent" to correctly evaluate ${} + // NOTE: expressions, in the future find a way to make it store as a + // NOTE: child vs. facet (possible if I create the LayoutComponent). + if (parent != null) { + parent.getFacets().remove(id); + parent.getChildren().add(node); + } + + // Configure TreeNode + configureTreeNode(ctx, adaptor, node, currentObj); + + // Walk TreeAdaptor and Create child TreeNodes + List children = adaptor.getChildTreeNodeObjects(currentObj); + if (children != null) { + Iterator it = children.iterator(); + while (it.hasNext()) { + currentObj = it.next(); + // We can ignore the return value b/c the factory should + // automatically set the parent + processNode(ctx, adaptor, currentObj, node); + } + } + + // Return the recently created TreeNode (or whatever it is) + return node; + } + + /** + *

    Adds on facets and handlers.

    + */ + protected void configureTreeNode(FacesContext ctx, TreeAdaptor adaptor, UIComponent treeNode, Object currentObj) { + // Add facets (such as "content" and "image") + Map facets = adaptor.getFacets(treeNode, currentObj); + if (facets != null) { + Map treeNodeFacets = treeNode.getFacets(); + Iterator it = facets.keySet().iterator(); + String facetName; + UIComponent facetValue; + while (it.hasNext()) { + facetName = it.next(); + facetValue = facets.get(facetName); + if (facetValue != null) { + treeNodeFacets.put(facetName, facetValue); + } + } + } + + // Add instance handlers + Map> handlersByType = + adaptor.getHandlersByType(treeNode, currentObj); + if (handlersByType != null) { + Iterator it = handlersByType.keySet().iterator(); + if (it.hasNext()) { + String eventType = null; + Map compAttrs = treeNode.getAttributes(); + while (it.hasNext()) { + // Assign instance handlers to attribute for retrieval later + // (Retrieval must be explicit, see LayoutElementBase) + eventType = it.next(); + compAttrs.put(eventType, handlersByType.get(eventType)); + } + } + } + } + + /** + *

    This is the option that must be supplied when using this factory + * in order to specify which TreeAdaptor instance should be used. + * The value should be a fully qualified class name of a valid + * TreeAdaptor instance. The TreeAdaptor instance must have a + * public static TreeAdaptor getInstance(FacesContext, + * LayoutComponent, UIComponent) method in order to get access + * to an instance of the TreeAdaptor instance.

    + */ + public static final String TREE_ADAPTOR_CLASS = "treeAdaptorClass"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/TreeAdaptor.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/TreeAdaptor.java new file mode 100644 index 0000000..825e56f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/TreeAdaptor.java @@ -0,0 +1,129 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.tree; + +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; + +import com.sun.jsftemplating.layout.descriptors.handler.Handler; + + +/** + *

    This interface defines the methods required by + * {@link DynamicTreeNodeFactory}. By providing these methods, you are + * able to interface some tree structure with the + * {@link DynamicTreeNodeFactory} so that whole or partial trees can be + * created without having to do any tree conversion work (the work is done + * by the TreeAdaptor implementation in conjunction with the + * {@link DynamicTreeNodeFactory}).

    + * + *

    The TreeAdaptor implementation must have a public + * static TreeAdaptor getInstance(FacesContext, LayoutComponent, + * UIComponent) method in order to get access to an instance of the + * TreeAdaptor instance.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface TreeAdaptor { + + /** + *

    This method is called shortly after + * getInstance(FacesContext, LayoutComponent, UIComponent). It + * provides a place for post-creation initialization to take occur.

    + */ + public void init(); + + /** + *

    Returns the model object for the top TreeNode, this + * may contain sub TreeNodes.

    + */ + public Object getTreeNodeObject(); + + /** + *

    Returns child TreeNodes for the given + * TreeNode model Object.

    + */ + public List getChildTreeNodeObjects(Object nodeObject); + + /** + *

    This method returns the UIComponent factory class + * implementation that should be used to create a + * TreeNode for the given tree node model object.

    + */ + public String getFactoryClass(Object nodeObject); + + /** + *

    This method returns the "options" that should be supplied to the + * factory that creates the TreeNode for the given tree + * node model object.

    + * + *

    Some useful options for the standard TreeNode + * component include:

    + * + *

    • text
    • + *
    • url
    • + *
    • imageURL
    • + *
    • target
    • + *
    • action
    • + *
    • actionListener
    • + *
    • expanded
    + * + *

    See Tree / TreeNode component documentation for more details.

    + */ + public Map getFactoryOptions(Object nodeObject); + + /** + *

    This method returns the id for the given tree node + * model object.

    + */ + public String getId(Object nodeObject); + + /** + *

    This method returns any facets that should be applied to the + * TreeNode (comp). Useful facets for the sun + * TreeNode component are: "content" and "image".

    + * + *

    Facets that already exist on comp, or facets that + * are directly added to comp do not need to be returned + * from this method.

    + * + * @param comp The tree node UIComponent. + * @param nodeObject The (model) object representing the tree node. + */ + public Map getFacets(UIComponent comp, Object nodeObject); + + /** + *

    Advanced framework feature which provides better handling for + * things such as expanding TreeNodes, beforeEncode, and other + * events.

    + * + *

    This method should return a Map of List + * of Handler objects. Each List in the + * Map should be registered under a key that cooresponds + * to to the "event" in which the Handlers should be + * invoked.

    + */ + public Map> getHandlersByType(UIComponent comp, Object nodeObject); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/TreeAdaptorBase.java b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/TreeAdaptorBase.java new file mode 100644 index 0000000..cdd9aa4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/component/factory/tree/TreeAdaptorBase.java @@ -0,0 +1,175 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.component.factory.tree; + +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; + +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; + + +/** + *

    This class provides some of the implemenation for the methods required + * by the TreeAdaptor interface. This class may be extended to assist in + * implementing a TreeAdaptor implementation.

    + * + *

    The TreeAdaptor implementation must have a public + * static TreeAdaptor getInstance(FacesContext, LayoutComponent, + * UIComponent) method in order to get access to an instance of the + * TreeAdaptor instance.

    + * + * @see TreeAdaptor + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public abstract class TreeAdaptorBase implements TreeAdaptor { + + /** + *

    This Constructor does nothing. If you need to store a reference + * to the LayoutComponent or UIComponent + * associated with this TreeAdaptor, it may be more + * convenient to use a different constructor.

    + */ + protected TreeAdaptorBase() { + } + + /** + *

    This Constructor save the LayoutComponent and the + * UIComponent for easy use later.

    + */ + protected TreeAdaptorBase(LayoutComponent desc, UIComponent parent) { + setLayoutComponent(desc); + setParentUIComponent(parent); + } + + /** + *

    This method retrieves the LayoutComponent associated + * with this TreeAdaptor.

    + */ + public LayoutComponent getLayoutComponent() { + return _layoutComponent; + } + + /** + *

    This method sets the LayoutComponent associated + * with this TreeAdaptor.

    + */ + public void setLayoutComponent(LayoutComponent comp) { + _layoutComponent = comp; + } + + /** + *

    This method retrieves the UIComponent associated + * with this TreeAdaptor.

    + */ + public UIComponent getParentUIComponent() { + return _parent; + } + + /** + *

    This method sets the UIComponent associated with this + * TreeAdaptor.

    + */ + public void setParentUIComponent(UIComponent comp) { + _parent = comp; + } + + /** + *

    This method is called shortly after + * getInstance(FacesContext, LayoutComponent, UIComponent). It + * provides a place for post-creation initialization to take occur.

    + * + *

    This implemenation does nothing.

    + */ + public void init() { + } + + /** + *

    Returns the model object for the top TreeNode, this + * may contain sub TreeNodes.

    + * + *

    This implementation returns the value that was supplied by + * {@link #setTreeNodeObject(Object)}. If that method is not explicitly + * called, then this implementation will return null.

    + */ + public Object getTreeNodeObject() { + return _topNodeObject; + } + + /** + *

    This method stores the top tree node model object.

    + */ + public void setTreeNodeObject(Object nodeObject) { + _topNodeObject = nodeObject; + } + + /** + *

    This method returns the UIComponent factory class + * implementation that should be used to create a + * TreeNode for the given tree node model object.

    + */ + public String getFactoryClass(Object nodeObject) { + return "com.sun.jsftemplating.component.factory.sun.TreeNodeFactory"; + } + + /** + *

    This method returns any facets that should be applied to the + * TreeNode (comp). Useful facets for the sun + * TreeNode component are: "content" and "image".

    + * + *

    Facets that already exist on comp, or facets that + * are directly added to comp do not need to be returned + * from this method.

    + * + * @param nodeObject The (model) object representing the tree node. + */ + public Map getFacets(Object nodeObject) { + return null; + } + + /** + *

    Advanced framework feature which provides better handling for + * things such as expanding TreeNodes, beforeEncode, and other + * events.

    + * + *

    This method should return a Map of List + * of Handler objects. Each List in the + * Map should be registered under a key that cooresponds + * to to the "event" in which the Handlers should be + * invoked.

    + * + *

    This implementation returns null. This method must be overriden + * to take advantage of this feature.

    + */ + public Map> getHandlersByType(UIComponent comp, Object nodeObject) { + return null; + } + + + private Object _topNodeObject = null; + private LayoutComponent _layoutComponent = null; + private UIComponent _parent = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java new file mode 100644 index 0000000..7389433 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java @@ -0,0 +1,136 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.el; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.el.EvaluationException; +import javax.faces.el.VariableResolver; + + +/** + *

    This VariableResolver exists to resolve "page session" + * attributes. This concept, borrowed from NetDynamics / JATO, stores + * data w/ the page so that it is available throughout the life of the + * page. This is longer than request scope, but usually shorter than + * session. This implementation stores the attributes on the + * UIViewRoot.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class PageSessionResolver extends VariableResolver { + + /** + *

    Constructor.

    + */ + public PageSessionResolver(VariableResolver orig) { + super(); + _origVariableResolver = orig; + } + + /** + *

    This first delegates to the original VariableResolver, + * it then checks "page session" to see if the value exists.

    + */ + public Object resolveVariable(FacesContext context, String name) throws EvaluationException { + Object result = null; + // Check to see if expression explicitly asks for PAGE_SESSION + if (name.equals(PAGE_SESSION)) { + // It does, return the Map + UIViewRoot root = context.getViewRoot(); + result = getPageSession(context, root); + if (result == null) { + // No Map! That's ok, create one... + result = createPageSession(context, root); + } + } else { + if (_origVariableResolver != null) { + // Not explicit, let original resolver do its thing first... + result = _origVariableResolver.resolveVariable(context, name); + } + + if (result == null) { + // Original resolver couldn't find anything, check page session + Map map = + getPageSession(context, (UIViewRoot) null); + if (map != null) { + result = map.get(name); + } + } + } + return result; + } + + /** + *

    This method provides access to the "page session" + * Map. If it doesn't exist, it returns + * null. If the given UIViewRoot is null, + * then the current UIViewRoot will be used.

    + */ + public static Map getPageSession(FacesContext ctx, UIViewRoot root) { + if (root == null) { + root = ctx.getViewRoot(); + } + return (Map) + root.getAttributes().get(PAGE_SESSION_KEY); + } + + /** + *

    This method will create a new "page session" Map. It + * will overwrite any existing "page session" Map, so be + * careful.

    + */ + public static Map createPageSession(FacesContext ctx, UIViewRoot root) { + if (root == null) { + root = ctx.getViewRoot(); + } + // Create it... + Map map = new HashMap(4); + + // Store it... + root.getAttributes().put(PAGE_SESSION_KEY, map); + + // Return it... + return map; + } + + /** + *

    The original VariableResolver.

    + */ + private VariableResolver _origVariableResolver = null; + + /** + *

    The attribute key in which to store the "page" session Map.

    + */ + private static final String PAGE_SESSION_KEY = "_ps"; + + /** + *

    The name an expression must use when it explicitly specifies page + * session. ("pageSession")

    + */ + public static final String PAGE_SESSION = "pageSession"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/el/PermissionChecker.java b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PermissionChecker.java new file mode 100644 index 0000000..44d96d0 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PermissionChecker.java @@ -0,0 +1,1266 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.el; + +import java.util.ArrayList; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + *

    This class evaluates a Boolean equation. The supported functions / + * operators are:

    + * + *
    • $<type>{<key>} -- To read a value according to + * <type> using <key> (See: + * {@link VariableResolver}). (null is + * interpretted as false, non boolean values (besides the string + * "false") are interpretted to mean true)
    • + *
    • '(' and ')' can be used to override order of operation
    • + *
    • '!' negate a boolean value
    • + *
    • '|' logical OR
    • + *
    • '&' logical AND
    • + *
    • '=' String equals
    • + *
    • '<' less than between 2 Integers
    • + *
    • '>' greater than between 2 Integers
    • + *
    • '%' modulus of 2 Integers
    • + *
    + * + * + *

    Operator Precedence (for infix notation) is:

    + * + *
    • () -- Highest
    • + *
    • !
    • + *
    • %
    • + *
    • &
    • + *
    • |
    • + *
    • < and >
    • + *
    • =
    • + *
    + * + * @see VariableResolver + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class PermissionChecker { + + /** + * This is the constructor method that is required to create this object. + */ + public PermissionChecker(LayoutElement desc, UIComponent component, String infixStr) { + if (infixStr == null) { + infixStr = "false"; + } + setLayoutElement(desc); + setUIComponent(component); + setInfix(stripWhiteSpace(infixStr)); + } + + + /** + *

    This method sets the LayoutElement that is associated with the 'if' + * check being evaluated. This is not normally needed, it is only needed + * if the 'if' check contains an expression which requires a + * LayoutElement to be properly evaluated.

    + */ + protected void setUIComponent(UIComponent component) { + _component = component; + } + + + /** + *

    Retreives the LayoutElement associated with this PermissionChecker + * (only needed in cases where a expression requires a LayoutElement for + * evaluation).

    + */ + public UIComponent getUIComponent() { + return _component; + } + + + /** + *

    This method sets the LayoutElement that is associated with the 'if' + * check being evaluated. This is not normally needed, it is only needed + * if the 'if' check contains an expression which requires a + * LayoutElement to be properly evaluated.

    + */ + protected void setLayoutElement(LayoutElement desc) { + _desc = desc; + } + + + /** + *

    Retreives the LayoutElement associated with this PermissionChecker + * (only needed in cases where a expression requires a LayoutElement for + * evaluation).

    + */ + public LayoutElement getLayoutElement() { + return _desc; + } + + + /** + *

    This method returns the precedence of the given operator. This + * only applies to infix notation (of course) and is needed to + * correctly order the operators when converting to postfix.

    + * + *
    • ! (not) has the highest precedence
    • + *
    • % (modulus)
    • + *
    • & (and)
    • + *
    • | (or)
    • + *
    • < (less than) and > (greater than)
    • + *
    • = (equals)
    • + *
    + * + *

    Of course '(' and ')' can be used to override the order of + * operations in infix notation.

    + * + * @param op The operator to evaluate. + * + * @return A number that can be used to compare its precedence. + */ + private static int getPrecedence(char op) { + switch (op) { + case LEFT_PAREN: + return 1; + case RIGHT_PAREN: + return 999; + case EQUALS_OPERATOR: + return 2; + case LESS_THAN_OPERATOR: + case MORE_THAN_OPERATOR: + return 4; + case OR_OPERATOR: + return 8; + case AND_OPERATOR: + return 16; + case MODULUS_OPERATOR: + case DIVIDE_OPERATOR: + return 32; + case NOT_OPERATOR: + return 64; + } + return 1; + } + + /** + *

    This method replaces all "true" / "false" strings w/ 't'/'f'. It + * converts the String into a char[]. It replaces all user defined + * functions w/ 'F' and places a Function in a list per the registered + * user-defined function. All other strings are converted to an 'F' + * and a StringFunction is added to the function list.

    + */ + protected char[] preProcessString(String source) { + char[] arr = source.toCharArray(); + int sourceLen = arr.length; + int destLen = 0; + + // Loop through the String, char by char + for (int idx = 0; idx < sourceLen; idx++) { + switch (arr[idx]) { + case POST_TRUE: + case POST_TRUE_CAP: + if (((idx + TRUE.length()) <= sourceLen) + && TRUE.equalsIgnoreCase( + new String(arr, idx, TRUE.length()))) { + arr[destLen++] = POST_TRUE; + idx += TRUE.length() - 1; + } else { + idx = storeFunction(arr, idx); + arr[destLen++] = FUNCTION_MARKER; + } + break; + case POST_FALSE: + case POST_FALSE_CAP: + if (((idx + FALSE.length()) <= sourceLen) + && FALSE.equalsIgnoreCase( + new String(arr, idx, FALSE.length()))) { + arr[destLen++] = POST_FALSE; + idx += FALSE.length() - 1; + } else { + idx = storeFunction(arr, idx); + arr[destLen++] = FUNCTION_MARKER; + } + break; + case OR_OPERATOR: + case EQUALS_OPERATOR: + case LESS_THAN_OPERATOR: + case MORE_THAN_OPERATOR: + case MODULUS_OPERATOR: + case DIVIDE_OPERATOR: + case AND_OPERATOR: + case NOT_OPERATOR: + case LEFT_PAREN: + case RIGHT_PAREN: + arr[destLen++] = arr[idx]; + break; + default: + idx = storeFunction(arr, idx); + arr[destLen++] = FUNCTION_MARKER; + } + } + char[] dest = new char[destLen]; + for (int idx = 0; idx < destLen; idx++) { + dest[idx] = arr[idx]; + } + return dest; + } + + /** + *

    This method looks at the given char array starting at index and + * continues until an operator (or end of String) is encountered. It + * then uses this string to lookup a registered function (if any), it + * stores that function (with parameters)... or if the function is + * not found, it registers a "String function" (which always returns + * true).

    + */ + protected int storeFunction(char[] arr, int idx) { + // Find string... + int start = idx; + int len = arr.length; + while ((idx < len) && !isOperator(arr[idx])) { + idx++; + } + + // Create String... + String str = new String(arr, start, idx - start); + + // Check to see if it is a registered function... + Function function = getFunction(str); + if (function != null) { + // Find the left paren... + int left = idx; + if ((left >= len) || (arr[left] != LEFT_PAREN)) { + throw new RuntimeException("Function '" + str + + "' is expected to have a '" + LEFT_PAREN + + "' immediately following it. Equation: '" + + new String(arr) + "'."); + } + + List arguments = new ArrayList(); + + // Find the right Paren... + while ((++idx < len) && (arr[idx] != RIGHT_PAREN)) { + if (arr[idx] == ARGUMENT_SEPARATOR) { + left++; + arguments.add(new String(arr, left, idx - left)); + left = idx; + } + } + + // Make sure we don't have () + left++; + if (idx > left) { + arguments.add(new String(arr, left, idx - left)); + } + + // Set the arguments... + function.setArguments(arguments); + } else { + // Not a registered function... + idx--; // In this case, there are no ()'s to consume, backup 1 + /* + if ((str.charAt(0) == FUNCTION_MARKER) && (str.length() == 1) + && !_tmpFunctionStack.empty()) { + // We have a function added during the subtitute() phase + function = (Function) _tmpFunctionStack.pop(); + } else { + */ + // Create a StringFunction + function = new StringFunction(str); + /* + } + */ + } + + // Add the function to the function list + _functionList.add(function); + + // Return the number of characters that we consumed... + return idx; + } + + /** + *

    This returns a Map<String, Class> which + * represent user-registered functions.

    + */ + private static Map getFunctions(FacesContext ctx) { + Map funcs = null; + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + if (ctx != null) { + Map appMap = + ctx.getExternalContext().getApplicationMap(); + funcs = (Map) appMap.get(PERMISSION_FUNCTIONS); + if (funcs == null) { + // Perhaps a SoftReference would be a good idea here? + funcs = new HashMap(); + } + } else { + // Not JSF env, create every time... + funcs = new HashMap(); + } + return funcs; + } + + /** + *

    This sets a Map<String, Class> which + * represent user-registered functions.

    + */ + private static void setFunctions(FacesContext ctx, Map map) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + if (ctx != null) { + // Only set if we're in a JSF env + ctx.getExternalContext().getApplicationMap(). + put(PERMISSION_FUNCTIONS, map); + } + } + + /** + *

    This method is a factory method for constructing a new function + * based on the function name passed in. The function must be + * registered prior to invoking this method.

    + */ + protected static Function getFunction(String functionName) { + // Get the Function class + Class functionClass = getFunctions(null).get(functionName); + if (functionClass == null) { + return null; + } + + // Create a new instance + Function function = null; + try { + function = (Function) functionClass.newInstance(); + } catch (Exception ex) { + throw new RuntimeException("Unable to instantiate '" + + functionClass.getName() + "' for '" + + functionName + "'", ex); + } + + // Return the instance + return function; + } + + + /** + *

    This method allows arbitrary functions to be registered. Function + * names should only contain letters or numbers, other characters or + * whitespace may cause problems. No checking is done to ensure this, + * however.

    + * + *

    Functions will be expressed in an equation as follows:

    + * + *
    • function_name(param1,param2)
    + * + *

    Function parameters also should only contain alpha-numeric + * characters.

    + * + *

    Functions must implement PermissionChecker.Function interface

    + */ + public static void registerFunction(String functionName, Class function) { + // Get a copy of the existing f()'s + Map newFuncs = + new HashMap(getFunctions(null)); + if (function == null) { + // Remove it... + newFuncs.remove(functionName); + } else { + if (!Function.class.isAssignableFrom(function)) { + throw new RuntimeException("'" + function.getName() + + "' must implement '" + Function.class.getName() + "'"); + } + // Add it... + newFuncs.put(functionName, function); + } + + // Save new copy of function Map + setFunctions(null, newFuncs); + } + + + /** + *

    This method returns true if the given character is a valid + * operator.

    + */ + public static boolean isOperator(char ch) { + switch (ch) { + case LEFT_PAREN: + case RIGHT_PAREN: + case EQUALS_OPERATOR: + case LESS_THAN_OPERATOR: + case MORE_THAN_OPERATOR: + case MODULUS_OPERATOR: + case DIVIDE_OPERATOR: + case OR_OPERATOR: + case AND_OPERATOR: + case NOT_OPERATOR: +// case AT_OPERATOR: +// case POUND_OPERATOR: +// case DOLLAR_OPERATOR: +// case UP_OPERATOR: +// case STAR_OPERATOR: +// case TILDA_OPERATOR: +// case ARGUMENT_SEPARATOR: + return true; + } + return false; + } + + + /** + *

    This method calculates the postfix representation of the infix + * equation passed in. It returns the postfix equation as a + * char[].

    + * + * @param infixStr The infix representation of the equation. + * + * @return postfix representation of the equation as a char[] (the f()'s + * are removed and stored in _functionList). + */ + protected char [] generatePostfix(String infixStr) { + // Reset the _functionList + _functionList = new ArrayList(); + + // Convert string to our parsable format + char[] result = preProcessString(infixStr); +//System.out.println("DEBUG: Initial String: '"+infixStr+"'"); +//System.out.println("DEBUG: After Pre-process: '"+new String(result)+"'"); + int resultLen = result.length; + int postIdx = 0; + int precedence = 0; + Stack opStack = new Stack(); + + // Put f()'s directly into result, push operators into right order + for (int idx = 0; idx < resultLen; idx++) { + switch(result[idx]) { + case FUNCTION_MARKER: + case POST_TRUE: + case POST_FALSE: + result[postIdx++] = result[idx]; + break; + case LEFT_PAREN: + opStack.push(new Character(LEFT_PAREN)); + break; + case RIGHT_PAREN: + while (!opStack.empty() + && (((Character) opStack.peek()).charValue() + != LEFT_PAREN)) { + result[postIdx++] = + ((Character) opStack.pop()).charValue(); + } + if (!opStack.empty()) { + // Throw away the LEFT_PAREN that should still be there + opStack.pop(); + } + break; + default: + // clear stuff + precedence = getPrecedence(result[idx]); + while (!opStack.empty() + && (getPrecedence(((Character) opStack.peek()). + charValue()) >= precedence)) { + result[postIdx++] = + ((Character) opStack.pop()).charValue(); + } + + /* Put it on the stack */ + opStack.push(new Character(result[idx])); + break; + } + } + + // empty the rest of the stack to the result + while (!opStack.empty()) { + result[postIdx++] = ((Character) opStack.pop()).charValue(); + } + // Copy the result to the postfixStr + char[] postfixStr = new char[postIdx]; + for (int idx = 0; idx < postIdx; idx++) { + postfixStr[idx] = result[idx]; + } +//System.out.println("DEBUG: Postfix String: '"+new String(postfixStr)+"'"); + return postfixStr; + } + + + /** + *

    This method is invoked to determine if the equation evaluates to + * true or false.

    + */ + public boolean hasPermission() { + char[] postfixArr = getPostfixArr(); + int len = postfixArr.length; + Stack result = new Stack(); + result.push(FALSE_BOOLEAN_FUNCTION); // Default to false + boolean val1, val2; + Iterator it = _functionList.iterator(); + + // Iterate through the postfix array + for (int idx = 0; idx < len; idx++) { + switch (postfixArr[idx]) { + case POST_TRUE: + result.push(TRUE_BOOLEAN_FUNCTION); + break; + case POST_FALSE: + result.push(FALSE_BOOLEAN_FUNCTION); + break; + case FUNCTION_MARKER: + if (!it.hasNext()) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "' -- found function marker " + + "w/o cooresponding function!"); + } + result.push(it.next()); + break; + case EQUALS_OPERATOR: + try { + // Allow reg expression matching + String matchStr = result.pop().toString(); + val1 = result.pop().toString().matches(matchStr); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + result.push(val1 ? + TRUE_BOOLEAN_FUNCTION : FALSE_BOOLEAN_FUNCTION); + break; + case LESS_THAN_OPERATOR: + try { + // The stack reverses the order, so check greater than + val1 = Integer.parseInt(result.pop().toString()) + > Integer.parseInt(result.pop().toString()); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + result.push(val1 ? + TRUE_BOOLEAN_FUNCTION : FALSE_BOOLEAN_FUNCTION); + break; + case MORE_THAN_OPERATOR: + try { + // The stack reverses the order, so check less than + val1 = Integer.parseInt(result.pop().toString()) + < Integer.parseInt(result.pop().toString()); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + result.push(val1 ? + TRUE_BOOLEAN_FUNCTION : FALSE_BOOLEAN_FUNCTION); + break; + case MODULUS_OPERATOR: + try { + // The stack reverses the order... + int modNumber = + Integer.parseInt(result.pop().toString()); + int num = Integer.parseInt(result.pop().toString()); + result.push(new StringFunction("" + (num % modNumber))); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + break; + case DIVIDE_OPERATOR: + try { + // The stack reverses the order... + int divNumber = + Integer.parseInt(result.pop().toString()); + int num = Integer.parseInt(result.pop().toString()); + result.push(new StringFunction("" + (num / divNumber))); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + break; + case OR_OPERATOR: + try { + val1 = ((Function) result.pop()).evaluate(); + val2 = ((Function) result.pop()).evaluate(); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + result.push((val1 || val2) ? + TRUE_BOOLEAN_FUNCTION : FALSE_BOOLEAN_FUNCTION); + break; + case AND_OPERATOR: + try { + val1 = ((Function) result.pop()).evaluate(); + val2 = ((Function) result.pop()).evaluate(); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + result.push((val1 && val2) ? + TRUE_BOOLEAN_FUNCTION : FALSE_BOOLEAN_FUNCTION); + break; + case NOT_OPERATOR: + try { + val1 = ((Function) result.pop()).evaluate(); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + result.push((!val1) ? + TRUE_BOOLEAN_FUNCTION : FALSE_BOOLEAN_FUNCTION); + break; + } + } + + // Return the only element on the stack (hopefully) + try { + val1 = ((Function) result.pop()).evaluate(); + } catch (EmptyStackException ex) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "'.", ex); + } + if (!result.empty()) { + result.pop(); // We added a false that wasn't needed + if (!result.empty()) { + throw new RuntimeException("Unable to evaluate: '" + + toString() + "' -- values left on the stack."); + } + } + return val1; + } + + + /** + *

    This method returns the infix representation of the equation, in + * other words: the original String passed in.

    + */ + public String getInfix() { + return _infixStr; + } + + + /** + *

    This method sets the equation and forces a re-evaluation of the + * equation. It returns the postfix representation of the + * equation.

    + * + * @param equation The infix equation to use. + * + */ + public void setInfix(String equation) { + _infixStr = equation; + setPostfixArr(generatePostfix(equation)); + } + + + /** + *

    Getter for the post fix array. If it is currently null, an empty + * char[] array will be returned.

    + */ + protected char [] getPostfixArr() { + if (_postfixArr == null) { + _postfixArr = new char[] {' '}; + } + return _postfixArr; + } + + + /** + *

    Setter for the postfix array of chars.

    + */ + protected void setPostfixArr(char[] postfix) { + _postfixArr = postfix; + } + + + /** + *

    This method provides access to a String representation + * of the postfix equation held by this Object.

    + */ + public String getPostfix() { + if (getPostfixArr() == null) { + return ""; + } + return new String(getPostfixArr()); + } + + + /** + *

    Displays the infix and postfix version of the equation.

    + */ + public String toString() { + return _infixStr + " = " + toString(getPostfixArr()); + } + + + /** + *

    This toString(...) method generates just the postfix + * representation of the equation. The postfix notation is stored as + * a char[] and it has the functions removed from the char[]. This + * method iterates through the char[] and generates a String with the + * functions put back into the equation.

    + * + * @param post The char[] representation of the postfix equation. + */ + private String toString(char[] post) { + int len = post.length; + StringBuffer result = new StringBuffer(""); + Iterator it = _functionList.iterator(); + + for (int idx = 0; idx < len; idx++) { + switch (post[idx]) { + case POST_TRUE: + result.append(TRUE); + break; + case POST_FALSE: + result.append(FALSE); + break; + case FUNCTION_MARKER: + result.append((it.next()).toString()); + break; + default: + result.append(post[idx]); + } + } + + return result.toString(); + } + + + /** + *

    This method removes all whitespace from the given String.

    + */ + public static String stripWhiteSpace(String input) { + char[] arr = input.toCharArray(); + int len = arr.length; + int destLen = 0; + + // Loop through the array skipping whitespace + for (int idx = 0; idx < len; idx++) { + if (Character.isWhitespace(arr[idx])) { + continue; + } + arr[destLen++] = arr[idx]; + } + + // Return the result + return new String(arr, 0, destLen); + } + + + + + /** + *

    This class must be implemented by all user defined Functions.

    + * + *

    In addition to these methods, a toString() should be implemented + * that reconstructs the original format of the function (i.e. + * function_name(arg1,arg2...)).

    + */ + public static interface Function { + + /** + *

    This method returns the List of arguments.

    + */ + public List getArguments(); + + /** + *

    This method is invoked be the PermissionChecker to set the + * arguments.

    + */ + public void setArguments(List args); + + /** + *

    This method is invoked by the PermissionCheck to evaluate the + * function to true or false.

    + */ + public boolean evaluate(); + } + + /** + *

    StringFunction implements Function and + * serves as the default function. This function is special in that + * it is NEVER registered and is the only function that SHOULD NOT be + * followed by ()'s. This function will process embedded expressions + * and evaulate to false if the entire string evaulates to null. + * Otherwise it will return true. This Function ignores + * all arguments (arguments only apply if it is registered, which + * shouldn't be the case anyway).

    + */ + protected class StringFunction implements PermissionChecker.Function { + + /** + * Constructor. + * + * @param value The expression to evaluate. + */ + public StringFunction(String value) { + _value = value; + } + + /** + * Not used. + */ + public List getArguments() { + return null; + } + + /** + * Not used. + */ + public void setArguments(List args) { + } + + /** + *

    Determine if the value of the Function is + * true or false.

    + */ + public boolean evaluate() { + Object obj = getEvaluatedValue(); + if (obj == null) { + return false; + } + obj = obj.toString(); + if (obj.equals("")) { + return false; + } + if (((String) obj).equalsIgnoreCase("false")) { + return false; + } + return true; + } + + /** + *

    This methis uses the {@link VariableResolver} to evaluate the + * String and returns the result.

    + */ + public Object getEvaluatedValue() { + FacesContext ctx = FacesContext.getCurrentInstance(); + return ComponentUtil.getInstance(ctx).resolveValue( + ctx, getLayoutElement(), getUIComponent(), _value); + } + + /** + *

    This implementation of toString() returns the + * evaluated value, except when the value is (null) + * in which case it returns the empty string ("").

    + */ + public String toString() { + Object obj = getEvaluatedValue(); + if (obj == null) { + return ""; + } + return obj.toString(); + } + + private String _value; + } + + /** + *

    BooleanFunction is either true or + * false. It is used internally by + * PermissionChecker and is not needed outside + * PermissionChecker since the Strings "true" or "false" + * used in an equation are sufficient.

    + */ + protected static class BooleanFunction implements PermissionChecker.Function { + + /** + *

    Constructor (defaults to false).

    + */ + public BooleanFunction() { + } + + /** + *

    Constructor.

    + */ + public BooleanFunction(boolean value) { + _value = value; + } + + /** + *

    Not used.

    + */ + public List getArguments() { + return null; + } + + /** + *

    Not used.

    + */ + public void setArguments(List args) { + } + + /** + *

    Return the value of the Function; + * true or false.

    + */ + public boolean evaluate() { + return _value; + } + + /** + *

    This implementation prints the String "true" or + * "false" based on the stored value.

    + */ + public String toString() { + return _value ? "true" : "false"; + } + + private boolean _value = false; + } + + + /** + *

    This is here to provide some test cases. It only tests the + * conversion to postfix notation.

    + */ + public static void main(String[] args) { + PermissionChecker checker; + if (args.length > 0) { + for (int count = 0; count < args.length; count++) { + checker = new PermissionChecker(null, null, args[count]); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + } + } else { + boolean success = true; + checker = new PermissionChecker(null, null, "false|false"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("false|false = falsefalse|")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "true|false = truefalse|"); + success = false; + } + if (checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "true |false"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("true|false = truefalse|")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "true|false = truefalse|"); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "true&(false|true)"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("true&(false|true) = truefalsetrue|&")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "true&(false|true) = truefalsetrue|&"); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "true&false|true"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("true&false|true = truefalse&true|")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "true&false|true = truefalse&true|"); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "true&true|false&true"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("true&true|false&true = truetrue&falsetrue&|")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "true&true|false&true = truetrue&falsetrue&|"); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "!true|false&!(false|true)"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("!true|false&!(false|true) = true!falsefalsetrue|!&|")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "!true|false&!(false|true) = true!falsefalsetrue|!&|"); + success = false; + } + if (checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "!(!(true&!true)|!(false|false))|(true|false)&true"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("!(!(true&!true)|!(false|false))|(true|false)&true = truetrue!&!falsefalse|!|!truefalse|true&|")) { + + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "!(!(true&!true)|!(false|false))|(true|false)&true = truetrue!&!falsefalse|!|!truefalse|true&|"); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + // Test '=' + checker = new PermissionChecker(null, null, "false =false"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("false=false = falsefalse=")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "false=false = falsefalse="); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, " test= me "); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("test=me = testme=")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "test=me = testme="); + success = false; + } + if (checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, " this should work=thisshouldwork"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("thisshouldwork=thisshouldwork = thisshouldworkthisshouldwork=")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "thisshouldwork=thisshouldwork = thisshouldworkthisshouldwork="); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "false|ab=true"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("false|ab=true = falseab|true=")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "false|ab=true = falseab|true="); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "false|(ab=true)"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("false|(ab=true) = falseabtrue=|")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "false|ab=true = falseab|true="); + success = false; + } + if (checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "false|(ab=ab)"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("false|(ab=ab) = falseabab=|")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "false|ab=true = falseab|true="); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "!"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("! = !")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "! = !"); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, ""); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals(" = ")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + " = "); + success = false; + } + if (checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "!$escape{}"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("!$escape{} = !")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + "! = !"); + success = false; + } + if (!checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + checker = new PermissionChecker(null, null, "$escape{}"); + System.out.println("Output:\n" + checker.toString() + " (" + checker.hasPermission() + ")"); + if (!checker.toString().equals("$escape{} = ")) { + System.out.println("\tFAILED!"); + System.out.println("Should have been:\n" + " = "); + success = false; + } + if (checker.hasPermission()) { + System.out.println("\tFAILED!"); + System.out.println("hasPermission(" + checker.toString(checker.getPostfixArr()) + ") returned the wrong result!"); + success = false; + } + + if (success) { + System.out.println("\n\tALL TESTS PASSED!"); + } else { + System.out.println("\n\tNOT ALL TESTS PASSED!"); + } + } + } + + + /** + *

    This variable represents a "false" BooleanFunction.

    + */ + public static final BooleanFunction FALSE_BOOLEAN_FUNCTION = + new BooleanFunction(false); + + /** + *

    This variable represents a "true" BooleanFunction.

    + */ + public static final BooleanFunction TRUE_BOOLEAN_FUNCTION = + new BooleanFunction(true); + + + protected static final char POST_TRUE = 't'; + protected static final char POST_FALSE = 'f'; + protected static final char POST_TRUE_CAP = 'T'; + protected static final char POST_FALSE_CAP = 'F'; + + public static final String TRUE = "true"; + public static final String FALSE = "false"; + + // Function representation in postfix String + public static final char FUNCTION_MARKER = 'F'; + + // Operator constants + public static final char LEFT_PAREN = '('; + public static final char RIGHT_PAREN = ')'; + public static final char EQUALS_OPERATOR = '='; + public static final char OR_OPERATOR = '|'; + public static final char AND_OPERATOR = '&'; + public static final char NOT_OPERATOR = '!'; + public static final char LESS_THAN_OPERATOR = '<'; + public static final char MORE_THAN_OPERATOR = '>'; + public static final char MODULUS_OPERATOR = '%'; + public static final char DIVIDE_OPERATOR = '/'; + + // The COMMA separates function arguments... not really an operator + public static final char ARGUMENT_SEPARATOR = ','; + + // Reserved operators, although not currently used... +/* + * These may be added eventually + * + * public static final char AT_OPERATOR = '@'; + * public static final char POUND_OPERATOR = '#'; + * public static final char DOLLAR_OPERATOR = '$'; + * public static final char UP_OPERATOR = '^'; + * public static final char STAR_OPERATOR = '*'; + * public static final char TILDA_OPERATOR = '~'; + */ + + private static final String PERMISSION_FUNCTIONS = "__jsft_permFuncs"; + + /** + *

    This holds the infix equation.

    + */ + private String _infixStr = null; + + /** + *

    This holds the postfix equation.

    + */ + private char[] _postfixArr = null; + + /** + *

    This List holds the actual Function objects that correspond to the + * 'F' markers in the postfix string.

    + */ + private List _functionList = null; + + /** + *

    This List of functions maintains variableSubstitution Functions + * which happen out-of-order. They will be pulled from this list as + * placed into the actual _functionList when the are encountered + * during the preProcessing.

    + */ +// private Stack _tmpFunctionStack = null; + private LayoutElement _desc = null; + private UIComponent _component = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/el/VariableResolver.java b/jsftemplating/src/main/java/com/sun/jsftemplating/el/VariableResolver.java new file mode 100644 index 0000000..1d5a9fc --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/el/VariableResolver.java @@ -0,0 +1,1804 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.el; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Stack; +import java.util.StringTokenizer; + +import javax.faces.component.NamingContainer; +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; + +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutComposition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.util.LogUtil; +import com.sun.jsftemplating.util.MessageUtil; +import com.sun.jsftemplating.util.Util; + + +/** + *

    VariableResolver is used to parse expressions of the format.

    + * + *

    $<type>{<key>}

    + * + *

    <type> refers to a registerd {@link VariableResolver.DataSource}, + * custom {@link VariableResolver.DataSource}s can be registered via: + * {@link #setDataSource(FacesContext ctx, String key, + * VariableResolver.DataSource dataSource)}. However, there are many + * built-in {@link VariableResolver.DataSource} types that are + * pre-registered.

    + * + *

    Below are the pre-registered types:

    + * + *
    • {@link #ATTRIBUTE} -- {@link AttributeDataSource}
    • + *
    • {@link #APPLICATION} -- {@link ApplicationDataSource}
    • + *
    • {@link #BOOLEAN} -- {@link BooleanDataSource}
    • + *
    • {@link #CONSTANT} -- {@link ConstantDataSource}
    • + *
    • {@link #COPY_PROPERTY} -- {@link CopyPropertyDataSource}
    • + *
    • {@link #ESCAPE} -- {@link EscapeDataSource}
    • + *
    • {@link #EVAL} -- {@link EvalDataSource}
    • + *
    • {@link #HAS_FACET} -- {@link HasFacetDataSource}
    • + *
    • {@link #HAS_PROPERTY} -- {@link HasPropertyDataSource}
    • + *
    • {@link #INT} -- {@link IntDataSource}
    • + *
    • {@link #METHOD_BINDING} -- {@link MethodBindingDataSource}
    • + *
    • {@link #METHOD_EXPRESSION} -- {@link MethodExpressionDataSource}
    • + *
    • {@link #OPTION} -- {@link OptionDataSource}
    • + *
    • {@link #PAGE_SESSION} -- {@link PageSessionDataSource}
    • + *
    • {@link #PROPERTY} -- {@link PropertyDataSource}
    • + *
    • {@link #REQUEST_PARAMETER} -- + * {@link RequestParameterDataSource}
    • + *
    • {@link #RESOURCE} -- {@link ResourceBundleDataSource}
    • + *
    • {@link #SESSION} -- {@link SessionDataSource}
    • + *
    • {@link #STACK_TRACE} -- {@link StackTraceDataSource}
    • + *
    • {@link #THIS} -- {@link ThisDataSource}
    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class VariableResolver { + + /** + *

    This method will substitute variables into the given String, or + * return the variable if the substitution is the whole String. This + * method looks for the LAST occurance of startToken in the given + * String. It then searches from that location (if found) to the + * first occurance of typeDelim. The value inbetween is used as the + * type of substitution to perform (i.e. request attribute, session, + * etc.). It next looks for the next occurance of endToken. The + * value inbetween is used as the key passed to the + * {@link VariableResolver.DataSource} specified by the type. The + * String value from the {@link VariableResolver.DataSource} replaces + * the portion of the String from the startToken to the endToken. If + * this is the entire String, the Object is returned instead of the + * String value. This process is repeated until no more + * substitutions are * needed.

    + * + *

    This algorithm will accomodate nested variables (e.g. "${A{$x}}"). + * It also allows the replacement value itself to contain variables. + * Care should be taken to ensure that the replacement String included + * does not directly or indirectly refer to itself -- this will cause + * an infinite loop.

    + * + *

    There is one special case where the string to be evaluated begins + * with the startToken and ends with the endToken. In this case, + * string substitution is NOT performed. Instead the value of the + * request attribute is returned.

    + * + *

    This method has a "hack" attached at the end of its processing + * which looks at the resulting value and does magic. If the value is + * a String that starts with "#{" then it will attempt to locate a + * composition parameter matching the next token value and replace or + * merge its content with the value. It will replace the value if the + * value is in the format #{key}. If there is additonal information + * after "key", it will attempt to merge value from the template + * parameter with the content after "key". A default value may be + * provided for the template parameter by providing a ",default" (e.g. + * #{key,default}.

    + * + * @param ctx The FacesContext + * @param desc The closest LayoutElement to this string + * @param component The assoicated UIComponent + * @param string The string to be evaluated. + * @param startToken Marks the beginning "$" + * @param typeDelim Marks separation of type/variable "{" + * @param endToken Marks the end of the variable "}" + * + * @return The new string with substitutions, or the specified request + * attribute value. + */ + public static Object resolveVariables(FacesContext ctx, LayoutElement desc, UIComponent component, String string, String startToken, String typeDelim, String endToken) { + + int stringLen = string.length(); + int delimIndex; + int endIndex; + int parenSemi; + int startTokenLen = startToken.length(); + int delimLen = typeDelim.length(); + int endTokenLen = endToken.length(); + boolean expressionIsWholeString = false; + char firstEndChar = SUB_END.charAt(0); + char firstDelimChar = SUB_TYPE_DELIM.charAt(0); + char currChar; + String type; + Object variable; + + for (int startIndex = string.lastIndexOf(startToken); startIndex != -1; + startIndex = string.lastIndexOf(startToken, startIndex - 1)) { + + // Make sure the startToken isn't escaped + if ((startIndex > 0) && (string.charAt(startIndex-1) == ESCAPE_CHAR)) { + string = string.substring(0, startIndex-1) // Before '\\' + + string.substring(startIndex); // After + stringLen--; + startIndex--; + continue; + } + + // Find first typeDelim + delimIndex = string.indexOf(typeDelim, startIndex + startTokenLen); + if (delimIndex == -1) { + continue; + } + + // Next find the end token + parenSemi = 0; + endIndex = -1; + // Iterate through the string looking for the matching end + for (int curr = delimIndex + delimLen; curr < stringLen; ) { + // Get the next char... + currChar = string.charAt(curr); + if ((currChar == firstDelimChar) && typeDelim.equals( + string.substring(curr, curr + delimLen))) { + // Found the start of another... inc the semi + parenSemi++; + curr += delimLen; + continue; + } + if ((currChar == firstEndChar) && endToken.equals( + string.substring(curr, curr + endTokenLen))) { + parenSemi--; + if (parenSemi < 0) { + // Found the right one! + endIndex = curr; + break; + } + // Found one, but this isn't the right one + curr += endTokenLen; + continue; + } + curr++; + } + if (endIndex == -1) { + // We didn't find a matching end... + continue; + } + +/* + // Next find end token + endIndex = string.indexOf(endToken, delimIndex+delimLen); + matchingIndex = string.lastIndexOf(typeDelim, endIndex); + while ((endIndex != -1) && (matchingIndex != delimIndex)) { + // We found a endToken, but not the matching one...keep looking + endIndex = string.indexOf(endToken, endIndex+endTokenLen); + matchingIndex = string.lastIndexOf(typeDelim, + matchingIndex-delimLen); + } + if ((endIndex == -1) || (matchingIndex == -1)) { + continue; + } +*/ + + // Handle special case where string starts with startToken and ends + // with endToken (and no replacements inbetween). This is special + // because we don't want to convert the attribute to a string, we + // want to return it (this allows Object types). + if ((startIndex == 0) && (endIndex == string.lastIndexOf(endToken)) + && (string.endsWith(endToken))) { + // This is the special case... + expressionIsWholeString = true; + } + + // Pull off the type... + type = string.substring(startIndex + startTokenLen, delimIndex); + DataSource ds = getDataSource(ctx, type); + if (ds == null) { + if ((type.indexOf('<') > -1) || (type.indexOf('&') > -1) || + (type.indexOf('[') > -1) || (type.indexOf('#') > -1) || + (type.indexOf('$') > -1) || (type.indexOf('%') > -1) || + (type.indexOf('(') > -1) || (type.indexOf(')')) > -1) { + // Do not consider this a valid EL expression, continue... + continue; + } + throw new IllegalArgumentException("Invalid type '" + type + + "' in attribute value: '" + string + "'."); + } + + // Pull off the variable... + variable = string.substring(delimIndex + delimLen, endIndex); + + // Get the value... + variable = ds.getValue(ctx, desc, component, (String) variable); + if (expressionIsWholeString) { + if (variable instanceof String) { + // See if we need to do EL magic manipulation... + variable = replaceCompParams(ctx, desc, component, (String) variable); + } + return variable; + } + + // Make new string + string = string.substring(0, startIndex) + // Before replacement + ((variable == null) ? "" : variable.toString()) + + string.substring(endIndex + endTokenLen); // After + stringLen = string.length(); + } + + // Return the string + return replaceCompParams(ctx, desc, component, string); + } + + /** + *

    This method implements a "hack" which manipulates the given String + * when it starts with "#{". In this case, it will attempt to locate a + * composition parameter matching the next token and replace or merge + * its content with this String. It will replace the String if the + * value is in the format #{key}. If there is additonal content after + * "key" (besides a (,) comma), it will attempt to merge the value of + * the composition parameter matching key with the content after + * "key". A default value may be provided for the template parameter + * by providing a ",default" at the end of the expression (e.g. + * #{key,default}.

    + * + *

    This method does not support replacing template paramters in other + * locations within EL.

    + * + * @param ctx The FacesContext. + * @param string The String to evaluate and manipulate if necessary. + * + * @return The same String passed in, or a new one based on method + * description. + */ + private static Object replaceCompParams(FacesContext ctx, LayoutElement desc, UIComponent comp, String string) { + // Sanity check + if (string == null) { + return null; + } + + // First see if we have any params + Map globalParams = + LayoutComposition.getGlobalParamMap(ctx); + if (globalParams.size() == 0) { + // No mappings, nothing to do + return string; + } + + String token = null; + Object value = null; + int len, startEL, endEL = 0; + int loopStart = 0; + char chars[] = string.toCharArray(); + boolean foundAtLeastOne = false, isWholeString = false; + StringBuilder buff = null; + Stack stack = null; + + while (true) { + startEL = findOpenEL(chars, loopStart); + // Detect + while (startEL != -1) { + // Get the next token +// FIXME: This is not nearly adequate!! +// Need to find all real tokens in #{!(some == expression) || foo} + endEL = findChar(chars, startEL + 2, '}', '[', '.', '=', '>', '<', '!', '&', '|', '*', '+', '-', '?', '/', '%', '('); + if (endEL == -1) { + // Not a match, non-fatal + startEL = -1; + break; + } + token = string.substring(startEL + 2, endEL); + token = token.trim(); + + // Check to see if this is template param + value = globalParams.get(token); + if (value != null) { + // We're not done yet! This value is only a flag, we have to + // look at the composition stack to be accurate! + if (stack == null) { + stack = LayoutComposition.getCompositionStack(ctx); + } + value = LayoutComposition.findTemplateParam(stack, token); + break; + } + startEL = string.indexOf("#{", endEL + 1); + } + + if (startEL == -1) { + if (!foundAtLeastOne) { + // We didn't find anything to substitute + return string; + } + + // Append the rest of the String + buff.append(chars, loopStart, chars.length - loopStart); + + // We're done + break; + } + + // Only get here when we find one... + foundAtLeastOne = true; + if (buff == null) { + // Initialize the buffer + buff = new StringBuilder(100); + } + + // Check to see if this expression starts at the beginning + isWholeString = (startEL == 0); + + // Add everything before the "#{" + buff.append(chars, loopStart, startEL - loopStart); + + // We got "...#{replaceMe?*", look at the next char to see what to do + if (chars[endEL] == '}') { + // Swap everything, no merge + endEL++; // Move past '}' + if (isWholeString && (endEL >= chars.length)) { + // Special case, #{} is entire string, return it + return resolveVariables(ctx, desc, comp, value); + } + isWholeString = false; + + // Ok, we just take the String value of "value" and add it + if (value != null) { + buff.append(value); + } + } else { + // Merge... we're just going to strip off "#{}" from value and + // insert it for now, later we might support more. + int start = 0; + String strVal = value.toString(); + if (strVal.startsWith("#{")) { + start = 2; + } + int end = strVal.length(); + if (strVal.charAt(end - 1) == '}') { + end--; + } + + // Add merged content... + buff.append("#{").append(strVal, start, end); + + // Find the end of the rest of the #{}... + end = findChar(chars, endEL + 1, '}'); + if (end == -1) { + throw new IllegalArgumentException( + "EL has unterminated #{} expression: (" + string + ")"); + } + buff.append(chars, endEL, ++end - endEL); + endEL = end; + } + loopStart = endEL; + } + + // Replace ${}, return the result... + return resolveVariables(ctx, desc, comp, buff.toString()); + } + + /** + *

    This looks for the first occurance of "#{" in + * chars. It returns the index of the starting + * character, or -1 if not found.

    + */ + private static int findOpenEL(char chars[], int idx) { + // Allow for a minimum of 3 characters after the # (i.e. {x}) + int len = chars.length-3; + for (; idx This method searches the given chars from the + * startingIndex for any of the characters in + * matchChars.

    + */ + private static int findChar(char chars[], int idx, char ... matchChars) { + int len = chars.length; + for (; idxLayoutElement descriptor + * @param component The UIComponent + * @param value The value to resolve + * + * @return The result + */ + public static Object resolveVariables(LayoutElement desc, + UIComponent component, Object value) { + if (value == null) { + return null; + } + return VariableResolver.resolveVariables( + FacesContext.getCurrentInstance(), desc, component, value); + } + + /** + * This method replaces the ${..} variables with their attribute values. + * It will only do this for Strings and List's that contain Strings. + * + * @param ctx The FacesContext + * @param desc The LayoutElement descriptor + * @param component The UIComponent + * @param value The value to resolve + * + * @return The result + */ + public static Object resolveVariables(FacesContext ctx, LayoutElement desc, UIComponent component, Object value) { + if (value == null) { + return null; + } + if (value instanceof String) { + value = VariableResolver.resolveVariables( + ctx, + desc, + component, + (String) value, + VariableResolver.SUB_START, + VariableResolver.SUB_TYPE_DELIM, + VariableResolver.SUB_END); + } else if (value instanceof List) { + // Create a new List b/c invalid to change shared List + List list = ((List) value); + List newList = new ArrayList(list.size()); + Iterator it = list.iterator(); + while (it.hasNext()) { + newList.add(VariableResolver.resolveVariables( + ctx, desc, component, it.next())); + } + return newList; + } else if (value instanceof Object []) { + // Create a new array b/c invalid to change shared array + Object [] arr = (Object []) value; + Object [] newArr = new Object[arr.length]; + int idx = 0; + for (Object obj : arr) { + newArr[idx++] = VariableResolver.resolveVariables( + ctx, desc, component, obj); + } + return newArr; + } + return value; + } + + /** + *

    This method looks up the requested + * {@link VariableResolver.DataSource} by the given key. + * + * @param key The key identifying the desired + * {@link VariableResolver.DataSource} + * + * @return The requested {@link VariableResolver.DataSource} + */ + public static VariableResolver.DataSource getDataSource(FacesContext ctx, String key) { + // Get the Map... and pull off the value (may be null) + return VariableResolver.getDataSourceMap(ctx).get(key); + } + + /** + *

    Provides access to the application-scoped Map which stores the + * {@link VariableResolver#DataSource}'s for this application.

    + */ + private static Map getDataSourceMap(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Map dataSourceMap = null; + if (ctx != null) { + dataSourceMap = (Map) + ctx.getExternalContext().getApplicationMap().get(VR_APP_KEY); + } + if (dataSourceMap == null) { + // 1st time... initialize it + dataSourceMap = new HashMap(); + AttributeDataSource attrDS = new AttributeDataSource(); + dataSourceMap.put("", attrDS); + dataSourceMap.put(ATTRIBUTE, attrDS); + dataSourceMap.put(APPLICATION, new ApplicationDataSource()); + dataSourceMap.put(COPY_PROPERTY, new CopyPropertyDataSource()); + dataSourceMap.put(OPTION, new OptionDataSource()); + dataSourceMap.put(PAGE_SESSION, new PageSessionDataSource()); + dataSourceMap.put(PROPERTY, new PropertyDataSource()); + dataSourceMap.put(HAS_PROPERTY, new HasPropertyDataSource()); + dataSourceMap.put(HAS_FACET, new HasFacetDataSource()); + dataSourceMap.put(SESSION, new SessionDataSource()); + dataSourceMap.put(STACK_TRACE, new StackTraceDataSource()); + dataSourceMap.put(REQUEST_PARAMETER, new RequestParameterDataSource()); +// dataSourceMap.put(DISPLAY, new DisplayFieldDataSource()); + dataSourceMap.put(THIS, new ThisDataSource()); + dataSourceMap.put(ESCAPE, new EscapeDataSource()); + dataSourceMap.put(EVAL, new EvalDataSource()); + dataSourceMap.put(INT, new IntDataSource()); + dataSourceMap.put(BOOLEAN, new BooleanDataSource()); + dataSourceMap.put(CONSTANT, new ConstantDataSource()); + dataSourceMap.put(RESOURCE, new ResourceBundleDataSource()); + dataSourceMap.put(METHOD_BINDING, new MethodBindingDataSource()); + dataSourceMap.put(METHOD_EXPRESSION, new MethodExpressionDataSource()); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put( + VR_APP_KEY, dataSourceMap); + } + } + + // Return the map... + return dataSourceMap; + } + + /** + *

    This method sets the given {@link VariableResolver.DataSource} to + * be used for $[type]{...} when key matches type.

    + * + * @param key The key identifying the + * {@link VariableResolver.DataSource} + * @param dataSource The {@link VariableResolver.DataSource} + */ + public static synchronized void setDataSource(FacesContext ctx, String key, VariableResolver.DataSource dataSource) { + // Get the Map... and pull off the value (may be null) + // NOTE: This is not thread safe.... although this is very rare + VariableResolver.getDataSourceMap(ctx).put(key, dataSource); + } + + /** + *

    This interface defines a String substitution data source. This + * is used to retrieve values when a $<type>{<data>} is + * encountered within a parameter value.

    + * + *

    Implementations of this interface may register themselves + * statically to extend the capabilities of the ${} substitution + * mechanism.

    + */ + public interface DataSource { + /** + *

    This method should return the resolved value based on the + * given key and contextual information.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key); + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * Application-scoped attributes. It uses the data portion of the + * substitution String as a key to the Map.

    + */ + public static class ApplicationDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return ctx.getExternalContext().getApplicationMap().get(key); + } + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * HttpRequest attributes. It uses the data portion of the + * substitution String as a key to the HttpRequest attribute Map.

    + */ + public static class AttributeDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return ctx.getExternalContext().getRequestMap().get(key); + } + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * "option" values that are set on a {@link LayoutComponent}. It + * uses the data portion of the substitution String as a key to the + * {@link LayoutComponent}'s options. If a value is not found, it + * will walk up the LayoutComponent's parents looking for a defined + * value.

    + */ + public static class OptionDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. (null) if not found. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, UIComponent component, String key) { + Object value = null; + while ((value == null) && (desc != null)) { + if (desc instanceof LayoutComponent) { + value = ((LayoutComponent) desc).getEvaluatedOption(ctx, key, component); + } + desc = desc.getParent(); + } + return value; + } + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * PageSession attributes. It uses the data portion of the + * substitution String as a key to the PageSession attribute Map.

    + */ + public static class PageSessionDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, UIComponent component, String key) { + Map map = + PageSessionResolver.getPageSession(ctx, ctx.getViewRoot()); + Serializable value = null; + if (map != null) { + value = map.get(key); + } + return value; + } + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * HttpRequest Parameters. It uses the data portion of the + * substitution String as a key to the HttpRequest Parameter Map.

    + */ + public static class RequestParameterDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return ctx.getExternalContext().getRequestParameterMap().get(key); + } + } + + /** + *

    This {@link VariableResolver.DataSource} copies + * UIComponent properties. It uses the data portion of + * the substitution String as a key to the UIComponent's properties + * via the attribute map. If the property is null, it will attempt to + * look at the parent's properties.

    + */ + public static class CopyPropertyDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, UIComponent component, String key) { + return findPropertyValue(ctx, desc, component, key, true); + } + + public Object findPropertyValue(FacesContext ctx, LayoutElement desc, UIComponent component, String key, boolean checkVE) { + if (component == null) { + return ""; + } + + // Check to see if we should walk up the tree or not + int idx = key.indexOf(','); + boolean walk = false; + if (idx > 0) { + walk = Boolean.valueOf(key.substring(idx + 1).trim()).booleanValue(); + key = key.substring(0, idx); + } + + Object value = null; + if (checkVE) { + value = component.getValueExpression(key); + if (value == null) { + value = component.getAttributes().get(key); + } + } else { + value = component.getAttributes().get(key); + } + if (walk) { + while ((value == null) && (component.getParent() != null)) { + component = component.getParent(); + if (checkVE) { + value = component.getValueExpression(key); + if (value == null) { + value = component.getAttributes().get(key); + } + } else { + value = component.getAttributes().get(key); + } + } + } +/* + if (LogUtil.finestEnabled()) { + // Trace information + LogUtil.finest(this, "RESOLVING ('" + key + "') for ('" + + component.getId() + "'): '" + value + "'"); + } +*/ + return value; + } + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * UIComponent Properties. It uses the data portion of the + * substitution String as a key to the UIComponent's properties via + * the attribute Map. If the property is null, it will attempt to + * look at the parent's properties.

    + */ + public static class PropertyDataSource extends CopyPropertyDataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, UIComponent component, String key) { + return findPropertyValue(ctx, desc, component, key, false); + } + } + + /** + *

    This {@link VariableResolver.DataSource} tests if the given + * property exists on the UIComponent. It uses the data portion of + * the substitution String as a key to the UIComponent's properties + * via the attribute Map.

    + */ + public static class HasPropertyDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + boolean hasKey = component.getAttributes().containsKey(key); + if (!hasKey) { + // Check the getter... JSF sucks when wrt attrs vs. props + if ((component.getValueExpression(key) != null) || + (component.getAttributes().get(key) != null)) { + hasKey = true; + } + } + if (!hasKey && (desc instanceof LayoutComponent)) { + // In some cases, the component is a TemplateComponent child + return getValue( + ctx, desc.getParent(), component.getParent(), key); + } + return Boolean.valueOf(hasKey); + } + } + + /** + *

    This {@link VariableResolver.DataSource} tests if the given facet + * exists on the UIComponent. It uses the data portion of the + * substitution String as a key to the UIComponent's facets.

    + */ + public static class HasFacetDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + boolean hasFacet = component.getFacets().containsKey(key); + if (!hasFacet && (desc instanceof LayoutComponent)) { + // In some cases, the component is a TemplateComponent child + return getValue( + ctx, desc.getParent(), component.getParent(), key); + } + return Boolean.valueOf(hasFacet); + } + } + + /** + *

    This {@link VariableResolver.DataSource} simply returns the key + * that it is given. This is useful for supplying ${}'s around the + * string you wish to mark as a string. If not used, characters such + * as '=' will be interpretted as a separator causing your string to + * be split -- which can be very undesirable. Mostly useful in "if" + * statements.

    + */ + public static class EscapeDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return key; + } + } + + /** + *

    This {@link VariableResolver.DataSource} evaluates the given + * boolean expression.

    + */ + public static class EvalDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + PermissionChecker checker = new PermissionChecker(desc, component, key); + return Boolean.valueOf(checker.hasPermission()); + } + } + + /** + *

    This {@link VariableResolver.DataSource} converts the given + * key to a Boolean. This is needed because + * JSF does not do this for you. When you call + * UIComponent.getAttributes().put(key, value), + * value is expected to be the correct type. Often + * Boolean types are needed. This + * {@link VariableResolver.DataSource} provides a means to supply a + * Boolean value.

    + */ + public static class BooleanDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return Boolean.valueOf(key); + } + } + + /** + *

    This {@link VariableResolver.DataSource} converts the given + * key to an Integer. This is needed + * because JSF does not do this for you. When you call + * UIComponent.getAttributes().put(key, value), + * value is expected to be the correct type. Often + * Integer types are needed. This + * {@link VariableResolver.DataSource} provides a means to supply an + * Integer value.

    + */ + public static class IntDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return Integer.valueOf(key); + } + } + + /** + *

    This {@link VariableResolver.DataSource} allows access to constants + * in java classes. It expects the key to be a fully qualified Java + * classname plus the variable name. Example:

    + * + *

    $constant{java.lang.Integer.MAX_VALUE}

    + */ + public static class ConstantDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + // First check to see if we've already found the value before. + Object value = constantMap.get(key); + if (value == null) { + // Not found, lets resolve it, duplicate the old Map to avoid + // sync problems + Map map = new HashMap(constantMap); + value = resolveValue(map, key); + + // Replace the shared Map w/ this new one. + constantMap = map; + } + return value; + } + + /** + *

    This method resolves key. Key is expected to be in the + * format:

    + * + *

    some.package.Class.STATIC_VARIBLE

    + * + *

    This method will first resolve Class. It will then walk + * through all its variables adding each static final variable to + * the Map.

    + * + * @param map The map to add variables to + * @param key The fully qualified CONSTANT name + * + * @return The value of the CONSTANT, or null if not found + */ + private Object resolveValue(Map map, String key) { + int lastDot = key.lastIndexOf('.'); + if (lastDot == -1) { + throw new IllegalArgumentException("Unable to resolve '" + key + + "' in $constant{" + key + "}. '" + key + "' must be a " + + "fully qualified classname plus the constant name."); + } + + // Get the classname / constant name + String className = key.substring(0, lastDot); + + // Add all constants to the Map + try { + addConstants(map, Util.loadClass(className, key)); + } catch (ClassNotFoundException ex) { + RuntimeException iae = new IllegalArgumentException("'" + + className + "' was not found! This must be a valid " + + "classname. This was found in expression $constant{" + + key + "}."); + iae.initCause(ex); + throw iae; + } + + // The constant hopefully is in the Map now, null if not + return map.get(key); + } + + /** + * This method adds all constants in the given class to the Map. The + * Map key will be the fully qualified class name, plus a '.', plus + * the constant name. + * + * @param map Map to store cls + * @param cls The Class to store in map + */ + private void addConstants(Map map, Class cls) { + // Get the class name + String className = cls.getName(); + + // Get the fields + Field[] fields = cls.getFields(); + + // Add the static final fields to the Map + Field field = null; + for (int count = 0; count < fields.length; count++) { + field = fields[count]; + if (Modifier.isStatic(field.getModifiers()) + && Modifier.isFinal(field.getModifiers())) { + try { + map.put(className + '.' + field.getName(), + field.get(null)); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + } + } + + /** + * This embedded Map caches constant value lookups. It is static and + * is shared by all users. + */ + private static Map constantMap = new HashMap(); + } + + /** + *

    This {@link VariableResolver.DataSource} creates a MethodExpression + * from the supplied key. Example:

    + * + *

    $methodExpression{#{bean.key}}

    + */ + public static class MethodExpressionDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + Class [] args = EMPTY_CLASS_ARRAY; + key = key.trim(); + int commaIdx = key.lastIndexOf(','); + if (commaIdx != -1) { + if (key.endsWith("true")) { + args = ACTION_ARGS; + key = key.substring(0, commaIdx); + } else if (key.endsWith("false")) { + key = key.substring(0, commaIdx); + } + } + return ctx.getApplication().getExpressionFactory(). + createMethodExpression( + ctx.getELContext(), key, Object.class, args); + } + } + + /** + *

    This {@link VariableResolver.DataSource} creates a MethodBinding + * from the supplied key. Example:

    + * + *

    $methodBinding{#{bean.key}}

    + */ + public static class MethodBindingDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return ctx.getApplication().createMethodBinding(key, ACTION_ARGS); + } + } + + /** + *

    This {@link VariableResolver.DataSource} allows access to resource + * bundle keys. It expects the key to be a resource bundle key plus a + * '.' then the actual resouce bundle key Example:

    + * + *

    $resource{bundleID.bundleKey}

    + * + *

    The bundleID should not contain '.' characters. The bundleKey + * may.

    + */ + public static class ResourceBundleDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + // Get the Request attribute key + int separator = key.indexOf("."); + if (separator == -1) { + throw new IllegalArgumentException("'" + key + + "' is not in format: \"[bundleID].[bundleKey]\"!"); + } + String value = key.substring(0, separator); + + // Get the Resource Bundle + Object obj = ctx.getExternalContext().getRequestMap().get(value); + + // Make sure we have something... + if (obj == null) { + // Only check the request scope b/c the RB is request specific + // Should we throw an exception? For now return the key + return key; + } + + // Make sure its a RB + if (!(obj instanceof ResourceBundle)) { + throw new IllegalArgumentException("\"" + value + "\" in: \"" + + SUB_START + RESOURCE + SUB_TYPE_DELIM + key + SUB_END + + "\" did not resolve to a ResourceBundle! Found: \"" + + obj.getClass().getName() + "\" instead. (toString(): " + + obj.toString() + ")"); + } + ResourceBundle bundle = (ResourceBundle) obj; + + // Return the result of the ResouceBundle lookup + String str = null; + int argSep = key.indexOf(",", separator); + try { + if (argSep > -1) { + str = bundle.getString(key.substring(separator + 1, argSep)); + } else { + str = bundle.getString(key.substring(separator + 1)); + } + if (str == null) { + str = key; + } else { + // Parse arguments + if (argSep > -1) { + StringTokenizer st = new StringTokenizer(key.substring(argSep), ","); + String[] tokens = new String[st.countTokens()]; + int i = 0; + while (st.hasMoreTokens()) { + tokens[i++] = st.nextToken().trim(); + } + str = MessageUtil.getFormattedMessage(str, tokens); + } + } + } catch (MissingResourceException ex) { + if (LogUtil.configEnabled()) { + LogUtil.config("Unable to find key: '" + + key.substring(separator + 1) + + "' in ResourceBundle '" + value + + "'. Perhaps this needs to be added?", ex); + } else if (LogUtil.infoEnabled()) { + // Info log level, don't be verbose, just display a benign + // warning. + LogUtil.info("JSFT0003", + new Object[] {key.substring(separator + 1), value}); + } + str = key; + } + + return str; + } + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * HttpSession attributes. It uses the data portion of the + * substitution String as a key to the HttpSession Map.

    + */ + public static class SessionDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + return ctx.getExternalContext().getSessionMap().get(key); + } + } + + /** + *

    This {@link VariableResolver.DataSource} returns a strack trace + * (as a String) from the current Thread. The data + * portion of the "substitution String" is used as a message + * prefixing the trace.

    + */ + public static class StackTraceDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param component The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + // Get the trace information + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + int len = trace.length; + + // Create a String w/ this info... + StringBuffer buf = new StringBuffer(key + "\n"); + for (int idx = 0; idx < len; idx++) { + buf.append(trace[idx] + "\n"); + } + + // Return it. + return buf.toString(); + } + } + + /** + *

    This {@link VariableResolver.DataSource} provides access to + * DisplayField values. It uses the data portion of the substitution + * String as the DisplayField name to find. This is a non-qualified + * DisplayField name. It will walk up the View tree starting at the + * View object cooresponding to the LayoutElement which contained this + * expression. At each ContainerView, it will look for a child with + * a matching name.

    + public static class DisplayFieldDataSource implements DataSource { + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent component, String key) { + while (desc != null) { + View view = desc.getView(ctx); + if (view instanceof ContainerView) { + View child = null; +//FIXME: use a better way to find if 'key' is a child of 'view' + try { + child = (((ContainerView)(view)).getChild(key)); + } catch (Exception ex) { + } + if (child != null) { + return ((ContainerView) view).getDisplayFieldValue(key); + } + } + desc = desc.getParent(); + } + return null; + } + } + */ + + /** + *

    This class provides an implementation for the syntax $this{xyz} + * where xyz can be any of the following.

    + * + *
    • component -- Current UIComponent
    • + *
    • clientId -- Current UIComponent's client id
    • + *
    • id -- Current UIComponent's id
    • + *
    • layoutElement -- Current {@link LayoutElement}
    • + *
    • parent -- Parent UIComponent
    • + *
    • parentId -- Parent UIComponent's client id
    • + *
    • parentLayoutElement -- Parent {@link LayoutElement}
    • + *
    • namingContainer -- Nearest NamingContainer
    • + *
    • valueBinding -- ValueBinding representing the + * UIComponent
    • + *
    • children -- Current UIComponent's children
    • + *
    + */ + public static class ThisDataSource implements DataSource { + /** + *

    See class JavaDoc.

    + * + * @param ctx The FacesContext + * @param desc The LayoutElement + * @param comp The UIComponent + * @param key The key used to obtain information from this + * DataSource. + * + * @return The value resolved from key. + */ + public Object getValue(FacesContext ctx, LayoutElement desc, + UIComponent comp, String key) { + Object value = null; + + if ((key.equalsIgnoreCase(CLIENT_ID)) || (key.length() == 0)) { + value = comp.getClientId(ctx); + } else if (key.equalsIgnoreCase(ID)) { + value = comp.getId(); + } else if (key.equalsIgnoreCase(CHILDREN)) { + value = comp.getChildren(); + } else if (key.equalsIgnoreCase(COMPONENT)) { + value = comp; + } else if (key.equalsIgnoreCase(LAYOUT_ELEMENT)) { + value = desc; + } else if (key.equalsIgnoreCase(PARENT_ID)) { + value = comp.getParent().getId(); + } else if (key.equalsIgnoreCase(PARENT_CLIENT_ID)) { + value = comp.getParent().getClientId(ctx); + } else if (key.equalsIgnoreCase(PARENT)) { + value = comp.getParent(); + } else if (key.equalsIgnoreCase(PARENT_LAYOUT_ELEMENT)) { + value = desc.getParent(); + } else if (key.equalsIgnoreCase(NAMING_CONTAINER)) { + for (value = comp.getParent(); value != null; + value = ((UIComponent) value).getParent()) { + if (value instanceof NamingContainer) { + break; + } + } + } else if (key.equalsIgnoreCase(VALUE_BINDING)) { + // Walk backward up the tree generate the path + Stack stack = new Stack(); + String id = null; + // FIXME: b/c of a bug, the old behavior actually returned the + // FIXME: parent component... the next line is here to persist + // FIXME: this behavior b/c some code depends on this, fix this + // FIXME: when you have a chance. + comp = comp.getParent(); + while ((comp != null) && !(comp instanceof UIViewRoot)) { + id = comp.getId(); + if (id == null) { + // Generate an id based on the clientId + id = comp.getClientId(ctx); + id = id.substring(id.lastIndexOf( + NamingContainer.SEPARATOR_CHAR) + 1); + } + stack.push(id); + comp = comp.getParent(); + } + StringBuffer buf = new StringBuffer(); + buf.append("view"); + while (!stack.empty()) { + buf.append("['" + stack.pop() + "']"); + } + value = buf.toString(); + } else { + throw new IllegalArgumentException("'" + key + + "' is not valid in $this{" + key + "}."); + } + + return value; + } + + /** + *

    Defines "children" in $this{children}. Returns the + * UIComponent's children.

    + */ + public static final String CHILDREN = "children"; + + /** + *

    Defines "component" in $this{component}. Returns the + * UIComponent object.

    + */ + public static final String COMPONENT = "component"; + + /** + *

    Defines "clientId" in $this{clientId}. Returns + * the String representing the client id for the UIComponent.

    + */ + public static final String CLIENT_ID = "clientId"; + + /** + *

    Defines "id" in $this{id}. Returns the String representing + * the id for the UIComponent.

    + */ + public static final String ID = "id"; + + /** + *

    Defines "layoutElement" in $this{layoutElement}. Returns + * the LayoutElement.

    + */ + public static final String LAYOUT_ELEMENT = "layoutElement"; + + /** + *

    Defines "parent" in $this{parent}. Returns the + * parent UIComponent object.

    + */ + public static final String PARENT = "parent"; + + /** + *

    Defines "parentId" in $this{parentId}. Returns the + * parent UIComponent object's Id.

    + */ + public static final String PARENT_ID = "parentId"; + + /** + *

    Defines "parentClientId" in $this{parentClientId}. Returns the + * parent UIComponent object's client Id.

    + */ + public static final String PARENT_CLIENT_ID = "parentClientId"; + + /** + *

    Defines "parentLayoutElement" in $this{parentLayoutElement}. + * Returns the parent LayoutElement.

    + */ + public static final String PARENT_LAYOUT_ELEMENT = + "parentLayoutElement"; + + /** + *

    Defines "namingContainer" in $this{namingContainer}. Returns + * the nearest naming container object (i.e. the form).

    + */ + public static final String NAMING_CONTAINER = "namingContainer"; + + /** + *

    Defines "valueBinding" in $this{valueBinding}. Returns + * a ValueBinding to this UIComponent.

    + */ + public static final String VALUE_BINDING = "valueBinding"; + } + + /** + * The main function for this class provides some simple test cases. + * + * @param args The commandline arguments. + */ + public static void main(String[] args) { + String test = null; + String good = null; + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$escape($escape(LayoutElement))", "$", "(", ")"); + good = "LayoutElement"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$escape($escape(EEPersistenceManager))", "$", "(", ")"); + good = "EEPersistenceManager"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$es$cape$escape(EEPersistenceManager))", "$", "(", ")"); + good = "$es$capeEEPersistenceManager)"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$escape($escapeEEP$ersistenceManager))", "$", "(", ")"); + good = "$escapeEEP$ersistenceManager)"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$escape($escape(EEPersistenceManager)))", "$", "(", ")"); + good = "EEPersistenceManager)"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$escape($escape(EEPersistenceManager())", "$", "(", ")"); + good = "$escape(EEPersistenceManager()"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$escape($escape($escape(EEPersistenceManager()))==$escape(" + + "EEPersistenceManager()))", "$", "(", ")"); + good = "EEPersistenceManager()==EEPersistenceManager()"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + test = "" + VariableResolver.resolveVariables(null, null, null, + "$escape($escape($escape(EEPersistenceManager()))==$escape(" + + "EEPersistenceManager()))", "$", "(", ")"); + good = "EEPersistenceManager()==EEPersistenceManager()"; + System.out.println("Expected Result: '" + good + "'"); + System.out.println(" Result: '" + test + "'"); + if (!test.equals(good)) { + System.out.println("FAILED!!!!"); + } + + /* + for (int x = 0; x < 100000; x++) { + System.out.println("" + VariableResolver.resolveVariables( + null, null, null, + "$escape($escape(EEPers" + x + "istenceManager()))==$escape(" + + "EEPersistenceManager())", "$", "(", ")")); + } + */ + } + + /** + *

    Defines "attribute" in $attribute{...}. This allows you to + * retrieve an HttpRequest attribute.

    + */ + public static final String ATTRIBUTE = "attribute"; + + /** + *

    Defines "application" in $application{...}. This allows you to + * retrieve an application-scoped attribute.

    + */ + public static final String APPLICATION = "application"; + + /** + *

    Defines "copyProperty" in $copyProperty{...}. This allows you to + * copy a property from the current UIComponent (or search for the + * property to copy by passing in "propName,true".

    + */ + public static final String COPY_PROPERTY = "copyProperty"; + + /** + *

    Defines "option" in $option{...}. This allows you to obtain an + * "option" that is defined in a {@link LayoutComponent}.

    + */ + public static final String OPTION = "option"; + + /** + *

    Defines "pageSession" in $pageSession{...}. This allows you to + * retrieve a PageSession attribute.

    + */ + public static final String PAGE_SESSION = "pageSession"; + + /** + *

    Defines "property" in $property{...}. This allows you to + * retrieve a property from the UIComponent.

    + */ + public static final String PROPERTY = "property"; + + /** + *

    Defines "hasProperty" in $hasProperty{...}. This allows you to + * see if a property from the UIComponent exists.

    + */ + public static final String HAS_PROPERTY = "hasProperty"; + + /** + *

    Defines "hasFacet" in $hasFacet{...}. This allows you to + * see if a facet from the UIComponent exists.

    + */ + public static final String HAS_FACET = "hasFacet"; + + /** + *

    Defines "session" in $session{...}. This allows you to retrieve + * an HttpSession attribute. + */ + public static final String SESSION = "session"; + + /** + *

    Defines "stackTrace" in $stackTrace{...}. This allows you to get + * a stack trace from the current Thread. + */ + public static final String STACK_TRACE = "stackTrace"; + + /** + *

    Defines "requestParameter" in $requestParameter{...}. This allows + * you to retrieve a HttpRequest parameter (QUERY_STRING + * parameter).

    + */ + public static final String REQUEST_PARAMETER = "requestParameter"; + + /** + *

    Defines "display" in $display{...}. This allows you to retrive + * a DisplayField value.

    + public static final String DISPLAY = "display"; + */ + + /** + *

    Defines "this" in $this{...}. This allows you to retrieve a + * number of different objects related to the relative placement of + * this expression.

    + * + * @see ThisDataSource + */ + public static final String THIS = "this"; + + /** + *

    Defines "escape" in $escape{...}. This allows some reserved + * characters to be escaped in "if" attributes. Such as '=' or + * '|'.

    + */ + public static final String ESCAPE = "escape"; + + /** + *

    Defines "eval" in $eval{...}. This allows a boolean expression to + * be evaulated.

    + */ + public static final String EVAL = "eval"; + + /** + *

    Defines "boolean" in $boolean{...}. This converts the given + * String to a Boolean.

    + */ + public static final String BOOLEAN = "boolean"; + + /** + *

    Defines "browser" in $browser{...}. This checks properties of the + * browser that sent the request.

    + */ + public static final String BROWSER = "browser"; + + /** + *

    Defines "int" in $int{...}. This converts the given String to an + * Integer.

    + */ + public static final String INT = "int"; + + /** + *

    Defines "methodBinding" in $methodBinding{...}. This allows + * MethodBindings to be created.

    + */ + public static final String METHOD_BINDING = "methodBinding"; + + /** + *

    Defines "methodExpression" in $methodExpression{...}. This allows + * MethodExpressions to be created.

    + */ + public static final String METHOD_EXPRESSION = "methodExpression"; + + /** + *

    Defines "constant" in $constant{...}. This allows constants + * in java classes to be accessed.

    + */ + public static final String CONSTANT = "constant"; + + /** + *

    Defines "resource" in $resource{...}. This allows resource + * to be accessed.

    + */ + public static final String RESOURCE = "resource"; + + /** + * Constant defining the arguments required for a Action MethodBinding. + */ + private static final Class[] ACTION_ARGS = {ActionEvent.class}; + + /** + * Empty Class[] for methods that take no arguments. + */ + private static final Class[] EMPTY_CLASS_ARRAY = {}; + + /** + *

    Application scope key to hold the VariableResolver DataSources.

    + */ + public static final String VR_APP_KEY = "__jsft_vrds_map"; + + /** + * Escape character. + */ + public static final char ESCAPE_CHAR = '\\'; + + /** + * The '$' character marks the beginning of a substituion in a String. + */ + public static final String SUB_START = "$"; + + + /** + * The '(' character marks the beginning of the data content of a String + * substitution. + */ + public static final String SUB_TYPE_DELIM = "{"; + + + /** + * The ')' character marks the end of the data content for a String + * substitution. + */ + public static final String SUB_END = "}"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/ComponentHandlers.java b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/ComponentHandlers.java new file mode 100644 index 0000000..8833da8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/ComponentHandlers.java @@ -0,0 +1,522 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +/* + * ComponentHandlers.java + * + * Created on December 6, 2004, 11:06 PM + */ +package com.sun.jsftemplating.handlers; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.LayoutViewHandler; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.LayoutElementBase; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.util.LayoutElementUtil; + + +/** + *

    This class contains + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * methods that perform component functions.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ComponentHandlers { + + /** + *

    Default Constructor.

    + */ + public ComponentHandlers() { + } + + /** + *

    This handler returns the children of the given + * UIComponent.

    + * + *

    Input value: "parent" -- Type: UIComponent

    + * + *

    Output value: "children" -- Type: java.util.List

    + *

    Output value: "size" -- Type: java.lang.Integer

    + * + * @param context The HandlerContext. + */ + @Handler(id="getUIComponentChildren", + input={ + @HandlerInput(name="parent", type=UIComponent.class, required=true)}, + output={ + @HandlerOutput(name="children", type=List.class), + @HandlerOutput(name="size", type=Integer.class)}) + public static void getChildren(HandlerContext context) { + UIComponent parent = (UIComponent) context.getInputValue("parent"); + List list = parent.getChildren(); + context.setOutputValue("children", list); + context.setOutputValue("size", new Integer(list.size())); + } + + /** + *

    This handler replaces the given old UIComponent in the + * UIComponent tree with the given new + * UIComponent. If the new UIComponent is not + * specified or is null, the old UIComponent will simply + * be removed.

    + * + *

    Input value: "old" -- Type: UIComponent

    + *

    Input value: "new" -- Type: UIComponent

    + * + * @param context The HandlerContext. + */ + @Handler(id="replaceUIComponent", + input={ + @HandlerInput(name="old", type=UIComponent.class, required=true), + @HandlerInput(name="new", type=UIComponent.class, required=false)} + ) + public static void replaceUIComponent(HandlerContext context) { + // Get the old component which is to be replaced + UIComponent oldComp = (UIComponent) context.getInputValue("old"); + if (oldComp == null) { + throw new IllegalArgumentException( + "You must provide a non-null value for 'component'."); + } + + // Check for a replacement UIComponent + UIComponent newComp = (UIComponent) context.getInputValue("new"); + + // Get the child UIComponent list... + List list = oldComp.getParent().getChildren(); + if (newComp == null) { + // Nothing to replace it with, just do a remove... + list.remove(oldComp); + } else { + // Find the index to put the new UIComponent in the right place + int index = list.indexOf(oldComp); + list.set(index, newComp); + } + } + + /** + *

    This will build a UIComponent tree from a + * {@link LayoutElement}. You must pass in the {@link LayoutElement} + * that will be used to create the UIComponent tree. + * You may optionally pass in the parent UIComponent + * which will serve as the parent for the newly created + * UIComponent tree. The resulting + * UIComponent tree will be returned via the + * result output value. If more than 1 root node exists + * for the given LayoutElement, the last added to the + * parent will be returned. Typically, you will pass in + * a {@link LayoutComponent} as the layoutElement so + * there will only be 1.

    + * + *

    It is recommended that you *do* supply the parent since EL + * expressions may depend on this when creating the + * UIComponent tree.

    + * + *

    One possible use case for calling this method would be to have a + * dynamic "id" property of a {@link LayoutComponent}, call this + * method multiple times with different values set in the "id" + * property. Remember, that you should not change a + * {@link LayoutComponent} (or any {@link LayoutElement}) directly. + * It is only safe to have dynamic values through EL bindings #{}.

    + * + *

    Another reason to use this handler is to cause a portion of a + * UIComponent tree to be recreated. This of often + * desirable during Ajax requests so that factory options can be + * reevaluated.

    + * + *

    Input value: "layoutElement" -- Type: LayoutElement

    + *

    Input value: "parent" -- Type: UIComponent

    + * + *

    Output value: "result" -- Type: UIComponent

    + * + * @param context The HandlerContext. + */ + @Handler(id="buildUIComponentTree", + input={ + @HandlerInput(name="layoutElement", type=LayoutElement.class, required=true), + @HandlerInput(name="parent", type=UIComponent.class, required=false)}, + output={ + @HandlerOutput(name="result", type=UIComponent.class)} + ) + public static void buildUIComponentTree(HandlerContext context) { + LayoutElement desc = (LayoutElement) context.getInputValue("layoutElement"); + UIComponent parent = (UIComponent) context.getInputValue("parent"); + + // If they didn't give us a parent, make one one up... + if (parent == null) { + parent = new UIViewRoot(); + ((UIViewRoot) parent).setViewId("fake"); + } + + // Build it... + FacesContext facesCtx = context.getFacesContext(); + if (desc instanceof LayoutComponent) { + // Special case if LayoutComponent is the root node element + // The LayoutViewHandler assumes that the root node is not used + // because it was written assuming that the LayoutDefinition was + // always going to be passed in. The result is that it ignores + // the LayoutElement that is passed in and goes striaight to the + // children. This isn't what we want. Process the child here, + // then continue as normal. + UIComponent tmpParent = + ((LayoutComponent) desc).getChild(facesCtx, parent); + LayoutViewHandler.buildUIComponentTree(facesCtx, tmpParent, desc); + } else { + // Process normally (which in this path is probably not normal) + LayoutViewHandler.buildUIComponentTree(facesCtx, parent, desc); + } + + // Get the result to return... + String id = desc.getId(facesCtx, parent); + UIComponent result = parent.findComponent(id); + if (result == null) { + // First see if we can find it in the facet Map + if (desc instanceof LayoutComponent) { + result = parent.getFacets().get(id); + } else { +// FIXME: find a way to find a "facet child" if the root LayoutElement is not a LayoutComponent + } + + if (result == null) { + // Still not found, check children... + List children = parent.getChildren(); + if (children.size() > 0) { + // Return the last child added b/c we want to make sure + // we're returning something that we added, not something + // that already existed. While not perfect, this is + // reasonable. + result = children.get(children.size() -1); + } + } + } + + // Set the output... + context.setOutputValue("result", result); + } + + /** + *

    This handler creates a UIComponent. It requires you + * to pass in the componentType (type) and returns the + * new component via the output parameter component.

    + * + *

    Input value: "type" -- Type: String

    + *

    Input value: "parent" -- Type: UIComponent

    + * + *

    Output value: "component" -- Type: UIComponent

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="createComponent", + input={ + @HandlerInput(name="type", type=String.class, required=true), + @HandlerInput(name="id", type=String.class, required=false), + @HandlerInput(name="parent", type=UIComponent.class, required=false)}, + output={ + @HandlerOutput(name="component", type=UIComponent.class)} + ) + public static void createComponent(HandlerContext context) { + // Get the input... + String type = (String) context.getInputValue("type"); + UIComponent parent = (UIComponent) context.getInputValue("parent"); + String id = (String) context.getInputValue("id"); + if (id == null) { + id = LayoutElementUtil.getGeneratedId(type); + } + + // Create a LayoutComponent... + FacesContext ctx = context.getFacesContext(); + LayoutComponent desc = new LayoutComponent((LayoutComponent) null, id, + LayoutDefinitionManager.getGlobalComponentType(ctx, type)); + + // Create the component... + UIComponent component = ComponentUtil.getInstance(ctx).createChildComponent( + ctx, desc, parent); + + // Return the result... + context.setOutputValue("component", component); + } + + /** + *

    This handler sets a UIComponent attribute / + * property.

    + * + *

    Input value: "component" -- Type: UIComponent

    + *

    Input value: "property" -- Type: String

    + *

    Input value: "value" -- Type: Object

    + * + * @param context The HandlerContext. + */ + @Handler(id="setUIComponentProperty", + input={ + @HandlerInput(name="component", type=UIComponent.class, required=true), + @HandlerInput(name="property", type=String.class, required=true), + @HandlerInput(name="value")}) + public static void setComponentProperty(HandlerContext context) { + UIComponent component = + (UIComponent) context.getInputValue("component"); + String propName = (String) context.getInputValue("property"); + Object value = context.getInputValue("value"); + + // Set the attribute or property value + component.getAttributes().put(propName, value); + } + + /** + *

    This handler finds the requested UIComponent by + * clientId. It takes clientId as an input + * parameter, and returns component as an output + * parameter.

    + */ + @Handler(id="getUIComponent", + input={ + @HandlerInput(name="clientId", type=String.class, required=true)}, + output={ + @HandlerOutput(name="component", type=UIComponent.class)}) + public static void getUIComponent(HandlerContext context) { + UIComponent viewRoot = context.getFacesContext().getViewRoot(); + String clientId = (String) context.getInputValue("clientId"); + context.setOutputValue("component", viewRoot.findComponent(clientId)); + } + + /** + *

    This handler retrieves a property from the given + * UIComponent. It expects component and + * name as an input parameters, and returns + * value as an output parameter containing the value of + * the property.

    + */ + @Handler(id="getUIComponentProperty", + input={ + @HandlerInput(name="component", type=UIComponent.class, required=true), + @HandlerInput(name="name", type=String.class, required=true)}, + output={ + @HandlerOutput(name="value", type=Object.class)}) + public static void getUIComponentProperty(HandlerContext context) { + UIComponent comp = (UIComponent) context.getInputValue("component"); + String name = (String) context.getInputValue("name"); + if ((comp == null) || (name == null)) { + throw new IllegalArgumentException("This Handler requires non-null" + + " values for 'component' and 'name'. 'component' was" + + " specified as '" + + context.getHandler().getInputValue("component") + + "' and evaluated to '" + comp + "'. 'name' was" + + " specified as '" + + context.getHandler().getInputValue("name") + + "' and evaluated to '" + name + "'."); + } + Object value = comp.getAttributes().get(name); + context.setOutputValue("value", value); + } + + /** + *

    This handler retrieves the requested the "facet" from the given + * UIComponent. component or + * clientId for the component must be passed in. The + * facet name must also be specified. It will return + * the UIComponent found (or null) in the + * value output parameter.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="getFacet", + input={ + @HandlerInput(name="clientId", type=String.class, required=false), + @HandlerInput(name="component", type=UIComponent.class, required=false), + @HandlerInput(name="name", type=String.class, required=true)}, + output={ + @HandlerOutput(name="value", type=UIComponent.class)}) + public static void getFacet(HandlerContext context) { + // Get the UIComponent to use + UIComponent comp = getUIComponentFromInput(context); + + // Get the facet name + String clientId = "" + (String) context.getInputValue("name"); + + // Look for the facet + UIComponent value = null; + if (comp != null) { + value = comp.getFacets().get(clientId); + } + + // Return the UIComponent (or null) + context.setOutputValue("value", value); + } + + /** + *

    This handler encodes the given UIComponent. You can + * specify the UIComponent by clientId, or + * pass it in directly via the component input + * parameter.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="encodeUIComponent", + input={ + @HandlerInput(name="clientId", type=String.class, required=false), + @HandlerInput(name="component", type=UIComponent.class, required=false)} + ) + public static void encode(HandlerContext context) throws IOException { + // Get the UIComponent to use + UIComponent comp = getUIComponentFromInput(context); + + // Encode the component + LayoutElementBase.encodeChild(context.getFacesContext(), comp); + } + + /** + *

    This method simply helps resolve a UIComponent for + * handlers that allow them to be specified via "component" or + * "clientId". "component" takes precedence. If neither are + * supplied, an IllegalArgumentException is thrown.

    + * + * @param context The {@link HandlerContext}. + * + * @return The UIComponent or null (if clientId + * did not resolve it). + * + * @throws IllegalArgumentException If neither "clientId" or + * "component" are provided. + */ + private static UIComponent getUIComponentFromInput(HandlerContext context) { + UIComponent comp = (UIComponent) context.getInputValue("component"); + if (comp == null) { + String clientId = (String) context.getInputValue("clientId"); + if (clientId != null) { + UIComponent viewRoot = context.getFacesContext().getViewRoot(); + comp = viewRoot.findComponent(clientId); + } else { + throw new IllegalArgumentException( + "You must specify the component to use, or a clientId to " + + "locate the UIComponent to use."); + } + } + + // Return the UIComponent (may be null if clientId didn't resolve it) + return comp; + } + + + /** + *

    This handler will print out the structure of a + * UIComponent tree from the given UIComponent.

    + */ + @Handler(id="dumpUIComponentTree", + input={ + @HandlerInput(name="component", type=UIComponent.class, required=false)}, + output={ + @HandlerOutput(name="value", type=String.class)}) + public static void dumpUIComponentTree(HandlerContext context) { +// FIXME: Add flag to dump attributes also, perhaps facets should be optional as well? + // Find the root UIComponent to use... + UIComponent comp = (UIComponent) context.getInputValue("component"); + if (comp == null) { + Object eventObject = context.getEventObject(); + if (eventObject instanceof UIComponent) { + comp = (UIComponent) eventObject; + } else { + comp = context.getFacesContext().getViewRoot(); + if (comp == null) { + throw new IllegalArgumentException( + "Unable to determine UIComponent to dump!"); + } + } + } + + // Create the buffer and populate it... + StringBuffer buf = new StringBuffer("UIComponent Tree:\n"); + dumpTree(comp, buf, " "); + + context.setOutputValue("value", buf.toString()); + } + + /** + *

    This method recurses through the UIComponent tree to + * generate a String representation of its structure.

    + */ + private static void dumpTree(UIComponent comp, StringBuffer buf, String indent) { + // First add the current UIComponent + buf.append(indent + comp.getId() + " (" + comp.getClass().getName() + ") = (" + comp.getAttributes().get("value") + ")\n"); + + // Children... + Iterator it = comp.getChildren().iterator(); + if (it.hasNext()) { + buf.append(indent + " Children:\n"); + while (it.hasNext()) { + dumpTree(it.next(), buf, indent + " "); + } + } + + // Facets... + Map facetMap = comp.getFacets(); + Iterator facetNames = facetMap.keySet().iterator(); + if (facetNames.hasNext()) { + while (facetNames.hasNext()) { + String name = facetNames.next(); + buf.append(indent + " Facet (" + name + "):\n"); + dumpTree(facetMap.get(name), buf, indent + " "); + } + } + } + + /** + *

    This handler will print out the structure of a + * {@link LayoutElement} tree from the given LayoutElement.

    + */ + @Handler(id="dumpLayoutElementTree", + input={ + @HandlerInput(name="layoutElement", type=LayoutElement.class, required=false)}, + output={ + @HandlerOutput(name="value", type=String.class)}) + public static void dumpLayoutElementTree(HandlerContext context) { +// FIXME: Add flag to dump attributes also, perhaps facets should be optional as well? + // Find the root UIComponent to use... + LayoutElement elt = (LayoutElement) context.getInputValue("layoutElement"); + if (elt == null) { + elt = context.getLayoutElement(); + if (elt == null) { + throw new IllegalArgumentException( + "Unable to determine LayoutElement to dump!"); + } + } + + // Create the buffer and populate it... + StringBuffer buf = new StringBuffer("LayoutElement Tree:\n"); + LayoutElementUtil.dumpTree(elt, buf, " "); + + context.setOutputValue("value", buf.toString()); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/MetaDataHandlers.java b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/MetaDataHandlers.java new file mode 100644 index 0000000..f96b13f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/MetaDataHandlers.java @@ -0,0 +1,223 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +/* + * MetaDataHandlers.java + * + * Created on December 2, 2004, 3:06 AM + */ +package com.sun.jsftemplating.handlers; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.ViewRootUtil; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition; + + +/** + *

    This class contains + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * methods that perform common utility-type functions.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class MetaDataHandlers { + + /** + *

    Default Constructor.

    + */ + public MetaDataHandlers() { + } + + /** + *

    This handler provides information about all known (global) + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler}s. + * It allows an input value ("id") to be passed in, this is optional. + * If the value is supplied, it will return information about that + * handler only. If not supplied, it will return information about + * all handlers. Output is passed via output values "info", "ids", + * and "handler". "info" is always returned and contains a + * String of information. "ids" is always returned and + * contains a Set of global {@link HandlerDefinition} + * ids that may be passed into this method. "handler" is returned + * only if an id was specified and will contain the requested + * {@link HandlerDefinition}.

    + */ + @Handler(id="getGlobalHandlerInformation", + input={ + @HandlerInput(name="id", type=String.class, required=false) + }, + output={ + @HandlerOutput(name="info", type=String.class), + @HandlerOutput(name="ids", type=Set.class), + @HandlerOutput(name="value", type=HandlerDefinition.class) + }) + public static void getGlobalHandlerInformation(HandlerContext context) { + // Get the known global HandlerDefinitions + Map defs = + new TreeMap(LayoutDefinitionManager.getGlobalHandlerDefinitions()); + + // Provide a Set of ids + context.setOutputValue("ids", defs.keySet()); + + // If a single HandlerDefinition was requested, provide it + // Produce a String of information also + String key = (String) context.getInputValue("id"); + if (key != null) { + context.setOutputValue("value", defs.get(key)); + context.setOutputValue("info", defs.get(key).toString()); + } else { + Iterator it = defs.values().iterator(); + StringBuffer buf = new StringBuffer(""); + while (it.hasNext()) { + buf.append(it.next().toString()); + } + context.setOutputValue("info", buf.toString()); + } + } + + /** + *

    This handler provides information about all known (global) + * {@link ComponentType}s. It allows an input value ("id") to be + * passed in, this is optional. If the value is supplied, it will + * return information about that {@link ComponentType} only. If not + * supplied, it will return information about all + * {@link ComponentType}s. Output is passed via output values + * "info", "ids", and "value". "info" is always returned and + * contains a String of information. "ids" is always + * returned and contains a Set of global + * {@link ComponentType} ids that may be passed into this method. + * "value" is returned only if an id was specified and will contain + * the requested {@link ComponentType}.

    + */ + @Handler(id="getGlobalComponentTypeInformation", + input={ + @HandlerInput(name="id", type=String.class, required=false) + }, + output={ + @HandlerOutput(name="info", type=String.class), + @HandlerOutput(name="ids", type=Set.class), + @HandlerOutput(name="value", type=ComponentType.class) + }) + public static void getGlobalComponentTypeInformation(HandlerContext context) { + // Get the known global HandlerDefinitions + Map defs = new TreeMap( + LayoutDefinitionManager.getGlobalComponentTypes( + context.getFacesContext())); + + // Provide a Set of ids + context.setOutputValue("ids", defs.keySet()); + + // If a single HandlerDefinition was requested, provide it + // Produce a String of information also + String key = (String) context.getInputValue("id"); + if (key != null) { + // Return info for 1 ComponentType, return the type itself too + context.setOutputValue("value", defs.get(key)); + context.setOutputValue("info", defs.get(key).toString()); + } else { + // Return info for ALL ComponentTypes + Iterator it = defs.values().iterator(); + StringBuffer buf = new StringBuffer(""); + while (it.hasNext()) { + buf.append(it.next().toString()); + } + context.setOutputValue("info", buf.toString()); + } + } + + /** + *

    This handler finds the (closest) requested + * {@link LayoutComponent} for the given viewId / + * clientId. If the viewId is not supplied, + * the current UIViewRoot will be used. The + * {@link LayoutComponent} is returned via the component + * output parameter. If an exact match is not found, it will return + * the last {@link LayoutComponent} found while searching the tree -- + * this should be the last {@link LayoutComponent} in the hierarchy + * of the specified component.

    + * + *

    This is not an easy process since JSF components may not all be + * NamingContainers, so the clientId is not sufficient to + * find it. This is unfortunate, but we we have to deal with it.

    + */ + @Handler(id="getLayoutComponent", + input={ + @HandlerInput(name="viewId", type=String.class, required=false), + @HandlerInput(name="clientId", type=String.class, required=true)}, + output={ + @HandlerOutput(name="component", type=LayoutComponent.class)}) + public static void getLayoutComponent(HandlerContext ctx) { + // First get the clientId that we are going to attempt to walk. + String viewId = (String) ctx.getInputValue("viewId"); + String clientId = (String) ctx.getInputValue("clientId"); + + // Next, find it + LayoutComponent result = LayoutDefinitionManager.getLayoutComponent( + ctx.getFacesContext(), viewId, clientId); + + // Set the result + ctx.setOutputValue("component", result); + } + + /** + *

    This handler provides a way to get a {@link LayoutDefinition}.

    + */ + @Handler(id="getLayoutDefinition", + input={ + @HandlerInput(name="viewId", type=String.class, required=false)}, + output={ + @HandlerOutput(name="layoutDefinition", type=LayoutDefinition.class)}) + public static void getLayoutDefinition(HandlerContext ctx) { + // First get the viewId... + String viewId = (String) ctx.getInputValue("viewId"); + + // Find the LayoutDefinition + LayoutDefinition def = ViewRootUtil.getLayoutDefinition(viewId); + + // Set the result + ctx.setOutputValue("layoutDefinition", def); + } + + /** + *

    This handler returns true if jsft is running in debug mode.

    + */ + @Handler(id="isDebug", + output={ + @HandlerOutput(name="value", type=Boolean.class)}) + public static void isDebug(HandlerContext ctx) { + // Set the result + ctx.setOutputValue("value", + LayoutDefinitionManager.isDebug(ctx.getFacesContext())); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/NavigationHandlers.java b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/NavigationHandlers.java new file mode 100644 index 0000000..1a7153b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/NavigationHandlers.java @@ -0,0 +1,224 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +/* + * NavigationHandlers.java + * + * Created on December 6, 2004, 11:06 PM + */ +package com.sun.jsftemplating.handlers; + +import java.io.IOException; + +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; + + +/** + *

    This class contains + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * methods that perform navigation oriented actions.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class NavigationHandlers { + + /** + *

    Default Constructor.

    + */ + public NavigationHandlers() { + } + + /** + *

    This handler returns a UIViewRoot. If the + * id parameter is supplied it will return the requested + * UIViewRoot (this may fail and cause an exception). If + * the id is not supplied, it will return the + * current UIViewRoot. The result will be returned in + * an output parameter named viewRoot.

    + */ + @Handler(id="getUIViewRoot", + input={ + @HandlerInput(name="id", type=String.class) + }, + output={ + @HandlerOutput(name="viewRoot", type=UIViewRoot.class) + }) + public void getUIViewRoot(HandlerContext context) { + String pageName = (String) context.getInputValue("id"); + FacesContext ctx = context.getFacesContext(); + UIViewRoot root = null; + if (pageName == null) { + root = ctx.getViewRoot(); + } else { + if (pageName.charAt(0) != '/') { + // Ensure we start w/ a '/' + pageName = "/" + pageName; + } + root = ctx.getApplication().getViewHandler(). + createView(ctx, pageName); + } + context.setOutputValue("viewRoot", root); + } + + /** + *

    This method gives you a "resource URL" as defined by the + * ViewHandler's getActionURL(String + * url) method.

    + * + * @param handlerCtx The {@link HandlerContext}. + */ + @Handler(id="getActionURL", + input={ + @HandlerInput(name="url", type=String.class, required=true) + }, + output={ + @HandlerOutput(name="result", type=String.class) + }) + public static void getActionURL(HandlerContext handlerCtx) { + String url = (String) handlerCtx.getInputValue("url"); + FacesContext ctx = handlerCtx.getFacesContext(); + handlerCtx.setOutputValue("result", ctx.getApplication(). + getViewHandler().getActionURL(ctx, url)); + } + + /** + *

    This method gives you a "resource URL" as defined by the + * ViewHandler's getResourceURL(String + * url) method.

    + * + * @param handlerCtx The {@link HandlerContext}. + */ + @Handler(id="getResourceURL", + input={ + @HandlerInput(name="url", type=String.class, required=true) + }, + output={ + @HandlerOutput(name="result", type=String.class) + }) + public static void getResourceURL(HandlerContext handlerCtx) { + String url = (String) handlerCtx.getInputValue("url"); + FacesContext ctx = handlerCtx.getFacesContext(); + handlerCtx.setOutputValue("result", ctx.getApplication(). + getViewHandler().getResourceURL(ctx, url)); + } + + /** + *

    This handler navigates to the given page. page may + * either be a UIViewRoot or a String + * representing a UIViewRoot. Passing in a + * String name of a UIViewRoot will always + * create a new UIViewRoot. Passing in the + * UIViewRoot provides an opportunity to customize the + * UIComponent tree that will be displayed.

    + * + *

    The {@link #getUIViewRoot(HandlerContext)} handler provides a way + * to obtain a UIViewRoot.

    + * + *

    Input value: "page" -- Type: Object (should be a + * String or a UIViewRoot).

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="navigate", + input={ + @HandlerInput(name="page", type=Object.class, required=true) + }) + public static void navigate(HandlerContext context) { + Object page = context.getInputValue("page"); + UIViewRoot root = null; + FacesContext ctx = context.getFacesContext(); + if (page instanceof String) { + // Create a new UIViewRoot with the given id + String strPage = (String) page; + if (strPage.charAt(0) != '/') { + // Ensure we start w/ a '/' + strPage = "/" + strPage; + } + root = ctx.getApplication().getViewHandler(). + createView(ctx, strPage); + } else if (page instanceof UIViewRoot) { + // We recieved a UIViewRoot, use it... + root = (UIViewRoot) page; + } else { + throw new IllegalArgumentException("Type '" + + page.getClass().getName() + + "' is not valid. It must be a String or UIViewRoot."); + } + + // Set the UIViewRoot so that it will be displayed + ctx.setViewRoot(root); + } + + /** + *

    This handler redirects to the given page.

    + * + *

    Input value: "page" -- Type: String

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="redirect", + input={ + @HandlerInput(name="page", type=String.class, required=true) + }) + public static void redirect(HandlerContext context) { + String page = (String) context.getInputValue("page"); + FacesContext ctx = context.getFacesContext(); + try { + ctx.getExternalContext().redirect(page); + ctx.responseComplete(); + } catch (IOException ex) { + throw new RuntimeException( + "Unable to navigate to page '" + page + "'!", ex); + } + } + + /** + *

    This handler forwards to the given page. Normally you will want + * to do {@link #navigate} as that follows JSF patterns. This uses + * the raw dispatcher forward mechanism (via the ExternalContext).

    + * + *

    Input value: "url" -- Type: String

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="dispatch", + input={ + @HandlerInput(name="path", type=String.class, required=true) + }) + public static void dispatch(HandlerContext context) { + String path = (String) context.getInputValue("path"); + FacesContext ctx = context.getFacesContext(); + try { + ctx.getExternalContext().dispatch(path); + ctx.responseComplete(); + } catch (IOException ex) { + throw new RuntimeException( + "Unable to navigate to path '" + path + "'!", ex); + } + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/OptionsHandlers.java b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/OptionsHandlers.java new file mode 100644 index 0000000..04dd40f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/OptionsHandlers.java @@ -0,0 +1,139 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ + +/* + * OptionsHandlers.java + * + * Created on June 8, 2006, 5:01 PM + */ +package com.sun.jsftemplating.handlers; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; + +import javax.faces.model.SelectItem; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.util.Util; + + +/** + * + * @author Jennifer Chou + */ +public class OptionsHandlers { + + /** + * Creates a new instance of OptionsHandlers + */ + public OptionsHandlers() { + } + + /** + *

    This handler returns the Lockhart version of Options of the drop-down + * of the given labels and values. + * labels and values arrays must be equal in + * size and in matching sequence.

    + * + *

    Input value: labels -- Type: + * java.util.Collection

    + * + *

    Input value: values -- Type: + * java.util.Collection

    + * + *

    Output value: options -- Type: + * SelectItem[] (castable to Option[])

    + * + * @param context The HandlerContext. + */ + @Handler(id="getSunOptions", + input={ + @HandlerInput(name="labels", type=Collection.class, required=true), + @HandlerInput(name="values", type=Collection.class, required=true)}, + output={ + @HandlerOutput(name="options", type=SelectItem[].class)}) + public static void getSunOptions(HandlerContext context) throws Exception { + Collection labels = (Collection) context.getInputValue("labels"); + Collection values = (Collection) context.getInputValue("values"); + if (labels.size() != values.size()) { + throw new Exception("getSunOptions Handler input " + + "incorrect: Input 'labels' and 'values' size must be equal. " + + "'labels' size: " + labels.size() + " 'values' size: " + + values.size()); + } + + SelectItem[] options = + (SelectItem []) Array.newInstance(SUN_OPTION_CLASS, labels.size()); + String[] labelsArray = (String[])labels.toArray(new String[labels.size()]); + String[] valuesArray = (String[])values.toArray(new String[values.size()]); + for (int i =0; i < labels.size(); i++) { + SelectItem option = getSunOption(valuesArray[i], labelsArray[i]); + options[i] = option; + } + context.setOutputValue("options", options); + } + + /** + * Creates a Woodstock Option instance. + */ + private static SelectItem getSunOption(String value, String label) { + try { + return (SelectItem) SUN_OPTION_CONSTRUCTOR.newInstance(value, label); + } catch (InstantiationException ex) { + throw new RuntimeException("Unable to instantiate '" + + SUN_OPTION_CLASS + "'!", ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException("Unable to instantiate '" + + SUN_OPTION_CLASS + "'!", ex); + } catch (InvocationTargetException ex) { + throw new RuntimeException("Unable to instantiate '" + + SUN_OPTION_CLASS + "'!", ex); + } + } + + /** + *

    Method wich returns the constructor on the class with the given + * arguments. It will return null if any exceptions occur, no + * exceptions will be thrown from this method.

    + */ + private static Constructor noExceptionFindConstructor(Class cls, Class args[]) { + Constructor constructor = null; + try { + constructor = cls.getConstructor(args); + } catch (Exception ex) { + // Ignore... + } + return constructor; + } + + private static final Class SUN_OPTION_CLASS = + Util.noExceptionLoadClass("com.sun.webui.jsf.model.Option"); + private static final Constructor SUN_OPTION_CONSTRUCTOR = + noExceptionFindConstructor( + SUN_OPTION_CLASS, new Class[] {Object.class, String.class}); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/ScopeHandlers.java b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/ScopeHandlers.java new file mode 100644 index 0000000..241bc3c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/ScopeHandlers.java @@ -0,0 +1,486 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +/* + * ScopeHandlers.java + * + * Created on December 2, 2004, 3:06 AM + */ +package com.sun.jsftemplating.handlers; + +import java.io.Serializable; +import java.util.Formatter; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.prefs.Preferences; + +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.el.PageSessionResolver; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.resource.ResourceBundleManager; +import com.sun.jsftemplating.util.Util; + + +/** + *

    This class contains + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * methods that perform common utility-type functions.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ScopeHandlers { + + /** + *

    Default Constructor.

    + */ + public ScopeHandlers() { + } + + /** + *

    This handler gets a request attribute. It requires "key" as an + * input value. It returns "value" as an output value. Note this + * can also be done via #{requestScope["attributeName"]}.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="getAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true)}, + output={ + @HandlerOutput(name="value", type=Object.class)}) + public static void getAttribute(HandlerContext context) { + String key = (String) context.getInputValue("key"); + Object value = context.getFacesContext().getExternalContext(). + getRequestMap().get(key); + context.setOutputValue("value", value); + } + + /** + *

    This handler sets a request attribute. It requires "key" and + * "value" input values to be passed in.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="setAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="value", required=true)}) + public static void setAttribute(HandlerContext context) { + String key = (String) context.getInputValue("key"); + Object value = context.getInputValue("value"); + context.getFacesContext().getExternalContext(). + getRequestMap().put(key, value); + } + + /** + *

    This handler produces a String consisting of all the request + * attributes. It outputs this via the "value" output value.

    + */ + @Handler(id="dumpAttributes", + output={ + @HandlerOutput(name="value", type=String.class) + }) + public static void dumpAttributes(HandlerContext context) { + Map map = + context.getFacesContext().getExternalContext().getRequestMap(); + context.setOutputValue("value", formatAttributes(map)); + } + + /** + *

    This handler gets a "page" session attribute. It requires + * key as an input value. It returns value + * as an output value. You may pass in the page + * (UIViewRoot) as an input value via the + * page input value, if you don't the current + * UIViewRoot will be used.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="getPageSessionAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="page", type=UIViewRoot.class, required=false) + }, + output={ + @HandlerOutput(name="value", type=Serializable.class) + }) + public static void getPageSessionAttribute(HandlerContext context) { + // Get the Page Session Map + Map map = + PageSessionResolver.getPageSession( + context.getFacesContext(), + (UIViewRoot) context.getInputValue("page")); + + // Get the value to return + Serializable value = null; + if (map != null) { + value = map.get((String) context.getInputValue("key")); + } + + // Return the value + context.setOutputValue("value", value); + } + + /** + *

    This handler sets a page session attribute. It requires + * key and value input values to be passed + * in. page may optionally be passed in to specify the + * page (UIViewRoot) that should be used -- otherwise + * the current UIViewRoot is used.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="setPageSessionAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="value", type=Serializable.class, required=true), + @HandlerInput(name="page", type=UIViewRoot.class, required=false) + }) + public static void setPageSessionAttribute(HandlerContext context) { + UIViewRoot root = (UIViewRoot) context.getInputValue("page"); + FacesContext ctx = context.getFacesContext(); + + // Get the Page Session Map + Map map = + PageSessionResolver.getPageSession(ctx, root); + if (map == null) { + map = PageSessionResolver.createPageSession(ctx, root); + } + + // Set the page session value + map.put((String) context.getInputValue("key"), + (Serializable) context.getInputValue("value")); + } + + /** + *

    This handler produces a String consisting of all the page session + * attributes. It outputs this via the value output + * value. This handler optionally accepts the page input + * value (UIViewRoot) -- if not supplied the current + * UIViewRoot is used.

    + */ + @Handler(id="dumpPageSessionAttributes", + input={ + @HandlerInput(name="page", type=UIViewRoot.class, required=false) + }, + output={ + @HandlerOutput(name="value", type=String.class) + }) + public static void dumpPageSessionAttributes(HandlerContext context) { + // Get the Page Session Map + Map map = PageSessionResolver.getPageSession( + context.getFacesContext(), + (UIViewRoot) context.getInputValue("page")); + + // Return the formatted result + context.setOutputValue("value", formatAttributes(map)); + } + + /** + *

    This handler gets a session attribute. It requires "key" as an + * input value. It returns "value" as an output value. Note this + * can also be done via #{sessionScope["attributeName"]}.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="getSessionAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true)}, + output={ + @HandlerOutput(name="value", type=Object.class)}) + public static void getSessionAttribute(HandlerContext context) { + String key = (String) context.getInputValue("key"); + Object value = context.getFacesContext().getExternalContext(). + getSessionMap().get(key); + context.setOutputValue("value", value); + } + + /** + *

    This handler sets a session attribute. It requires "key" and + * "value" input values to be passed in.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="setSessionAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="value", required=true)}) + public static void setSessionAttribute(HandlerContext context) { + String key = (String) context.getInputValue("key"); + Object value = context.getInputValue("value"); + context.getFacesContext().getExternalContext(). + getSessionMap().put(key, value); + } + + /** + *

    This handler produces a String consisting of all the request + * attributes. It outputs this via the "value" output value.

    + */ + @Handler(id="dumpSessionAttributes", + output={ + @HandlerOutput(name="value", type=String.class) + }) + public static void dumpSessionAttributes(HandlerContext context) { + Map map = + context.getFacesContext().getExternalContext().getSessionMap(); + context.setOutputValue("value", formatAttributes(map)); + } + + /** + *

    This handler gets a application attribute. It requires "key" as an + * input value. It returns "value" as an output value. Note this + * can also be done via #{applicationScope["attributeName"]}.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="getApplicationAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true)}, + output={ + @HandlerOutput(name="value", type=Object.class)}) + public static void getApplicationAttribute(HandlerContext context) { + String key = (String) context.getInputValue("key"); + Object value = context.getFacesContext().getExternalContext(). + getApplicationMap().get(key); + context.setOutputValue("value", value); + } + + /** + *

    This handler sets a application attribute. It requires "key" and + * "value" input values to be passed in.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="setApplicationAttribute", + input={ + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="value", required=true)}) + public static void setApplicationAttribute(HandlerContext context) { + String key = (String) context.getInputValue("key"); + Object value = context.getInputValue("value"); + context.getFacesContext().getExternalContext(). + getApplicationMap().put(key, value); + } + + /** + *

    This handler produces a String consisting of all the request + * attributes. It outputs this via the "value" output value.

    + */ + @Handler(id="dumpApplicationAttributes", + output={ + @HandlerOutput(name="value", type=String.class) + }) + public static void dumpApplicationAttributes(HandlerContext context) { + Map map = + context.getFacesContext().getExternalContext().getApplicationMap(); + context.setOutputValue("value", formatAttributes(map)); + } + + /** + *

    This method formats attributes from a Map. This is + * used with the dump handlers.

    + */ + private static String formatAttributes(Map map) { + Formatter printf = new Formatter(); + if (map == null) { + printf.format("Map null."); + } else { + Iterator> it = map.entrySet().iterator(); + Map.Entry entry = null; + while (it.hasNext()) { + entry = it.next(); + printf.format("%-20s = %s\n", entry.getKey(), entry.getValue()); + } + } + return printf.toString(); + } + + /** + *

    This handler sets a ResourceBundle in desired request + * attribute. It requires "key" as an input value, which is the + * request attribute key used to store the bundle. "bundle" is also + * required as an input value, this is the fully qualified name of the + * bundle. Optionally the "locale" can be specified, if not the web + * user's locale will be used. It returns "bundle" as an output + * value.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="setResourceBundle", + input={ + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="bundle", type=String.class, required=true), + @HandlerInput(name="locale", type=Locale.class, required=false)}, + output={ + @HandlerOutput(name="result", type=ResourceBundle.class)}) + public static void setResourceBundle(HandlerContext context) { + // Get the input + String key = (String) context.getInputValue("key"); + String name = (String) context.getInputValue("bundle"); + Locale locale = (Locale) context.getInputValue("locale"); + FacesContext ctx = context.getFacesContext(); + if (locale == null) { + locale = Util.getLocale(ctx); + } + + // Get the ResourceBundle + ResourceBundle bundle = ResourceBundleManager.getInstance(ctx). + getBundle(name, locale); + + // Store it in the Request Map + ctx.getExternalContext().getRequestMap().put(key, bundle); + + // Return it + context.setOutputValue("result", bundle); + } + + /** + *

    This method provides access to the named cookie. If the cookie doesn't exist, the value + * will be set to ""

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="getCookie", + input={ + @HandlerInput(name="key", type=String.class, required=true)}, + output={ + @HandlerOutput(name="value", type=String.class)}) + public static void getCookie(HandlerContext context) { + Map cookies = context.getFacesContext(). + getExternalContext().getRequestCookieMap(); + Cookie cookie = (Cookie) cookies.get(context.getInputValue("key")); + context.setOutputValue("value", (cookie == null) ? "" : cookie.getValue()); + } + + /** + *

    This method set the named cookie with the given value. Because + * cookies are set via a response header, this method must be called + * before the content rendering has begun (before the rendering + * phase). This method is not valid for Portlets and will do nothing + * if called in a Portlet environment.

    + * + * @param context The {@link HandlerContext}. + */ + @Handler(id="setCookie", + input={ + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="value", type=String.class, required=true), + @HandlerInput(name="maxAge", type=Integer.class, defaultValue="-1", required=false), + @HandlerInput(name="domain", type=String.class, required=false), + @HandlerInput(name="path", type=String.class, required=false), + @HandlerInput(name="secure", type=Boolean.class, defaultValue="false", required=false), + @HandlerInput(name="version", type=Integer.class, required=false) + }) + public static void setCookie(HandlerContext context) { + Object resp = context.getFacesContext().getExternalContext().getResponse(); + if (resp instanceof HttpServletResponse) { + // Create a Cookie + Cookie cookie = new Cookie( + (String) context.getInputValue("key"), + (String) context.getInputValue("value")); + + // Set Max Age + cookie.setMaxAge((Integer) context.getInputValue("maxAge")); + + // Set Domain + String domain = (String) context.getInputValue("domain"); + if (domain != null) { + cookie.setDomain(domain); + } + + // Set Path + String path = (String) context.getInputValue("path"); + if (path != null) { + cookie.setPath(path); + } + + // Set Secure Flag + cookie.setSecure((Boolean) context.getInputValue("secure")); + + // Set version (0 = orig Netscape; 1= RFC 2109) + Integer version = (Integer) context.getInputValue("version"); + if (version != null) { + cookie.setVersion(version); + } + + // Add the cookie + ((HttpServletResponse) resp).addCookie(cookie); + } + } + + /** + *

    This {@link Handler} allows you to set a preference via the Java + * Preferences API. The root specifies the path in + * which the preference should be stored (e.g. '/org/company/foo'). + * The key is the name of the preference, and the + * value is the value of the preference.

    + */ + @Handler(id="setPreference", + input={ + @HandlerInput(name="root", type=String.class, required=true), + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="value", type=String.class, required=true) + }) + public static void setPreference(HandlerContext context) { + String nodeKey = (String) context.getInputValue("root"); + String key = (String) context.getInputValue("key"); + String value = (String) context.getInputValue("value"); + Preferences prefs = Preferences.userRoot().node(nodeKey); + prefs.put(key, value); + } + + /** + *

    This {@link Handler} allows you to get a preference via the Java + * Preferences API. The root specifies the path in + * which the preference should be stored (e.g. '/org/company/foo'). + * The key is the name of the preference, and the + * default is the value of the preference if it does + * not yet exist. The preference value will be returned via the + * value output value.

    + */ + @Handler(id="getPreference", + input={ + @HandlerInput(name="root", type=String.class, required=true), + @HandlerInput(name="key", type=String.class, required=true), + @HandlerInput(name="default", type=String.class) + }, + output={ + @HandlerOutput(name="value", type=String.class) + }) + public static void getPreference(HandlerContext context) { + String nodeKey = (String) context.getInputValue("root"); + String key = (String) context.getInputValue("key"); + String def = (String) context.getInputValue("default"); + Preferences prefs = Preferences.userRoot().node(nodeKey); + String value = prefs.get(key, def); + context.setOutputValue("value", value); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/UtilHandlers.java b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/UtilHandlers.java new file mode 100644 index 0000000..752202c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/handlers/UtilHandlers.java @@ -0,0 +1,560 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +/* + * UtilHandlers.java + * + * Created on December 2, 2004, 3:06 AM + */ +package com.sun.jsftemplating.handlers; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Serializable; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.el.PageSessionResolver; +import com.sun.jsftemplating.layout.LayoutViewHandler; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.util.Util; + + +/** + *

    This class contains + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * methods that perform common utility-type functions.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class UtilHandlers { + + /** + *

    Default Constructor.

    + */ + public UtilHandlers() { + } + + /** + *

    This handler uses the special "condition" attribute to determine if + * it should execute (and therefor any of its child handlers. So the + * implementation itself does nothing.

    + */ + @Handler(id="if", + input={@HandlerInput(name="condition", type=String.class)}) + public static void ifHandler(HandlerContext context) { + // Do nothing, the purpose of this handler is to provide condition + // support which is handled by the parser / runtime. + } + + /** + *

    A utility handler that resembles the for() method in Java. Handlers + * inside the for loop will be executed in a loop. The starting index + * is specified by start. The index will increase + * sequentially untill it is equal to end. + * var will be a request attribute that is set to the + * current index value as the loop iterates.

    + *

    For example:

    + * + * forLoop(start="1" end="3" var="foo") {...} + * + *

    The handlers inside the {...} will be executed 2 times + * (with foo=1 and foo=2).

    + * + *
    • start -- type: Integer Starting + * index, defaults to zero if not specified.
    • + *
    • end -- type: Integer; Ending index. + * Required.
    • + *
    • var -- type: String; Request + * attribute to be set in the for loop to the value of the + * index.
    + * + * @param handlerCtx The {@link HandlerContext}. + */ + @Handler(id="for", + input={ + @HandlerInput(name="start", type=Integer.class), + @HandlerInput(name="end", type=Integer.class, required=true), + @HandlerInput(name="var", type=String.class, required=true)}) + public static boolean forLoop(HandlerContext handlerCtx) { + Integer startInt = (Integer) handlerCtx.getInputValue("start"); + int start = (startInt == null) ? 0 : startInt; + int end = (Integer) handlerCtx.getInputValue("end"); + String var = (String) handlerCtx.getInputValue("var"); + + List handlers = + handlerCtx.getHandler().getChildHandlers(); + if (handlers.size() > 0) { + // We have child handlers in the loop... execute while we iterate + LayoutElement elt = handlerCtx.getLayoutElement(); + Map requestMap = handlerCtx.getFacesContext(). + getExternalContext().getRequestMap(); + for (int idx=start; idx < end; idx++) { + requestMap.put(var, idx); + // Ignore whats returned by the handler... we need to return + // false anyway to prevent children from being executed again + elt.dispatchHandlers(handlerCtx, handlers); + } + } + + // This will prevent the child handlers from executing again + return false; + } + + /** + *

    This handler writes using System.out.println. It + * requires that value be supplied as a String input + * parameter.

    + * + * @param context The HandlerContext. + */ + @Handler(id="println", + input={@HandlerInput(name="value", type=String.class, required=true)}) + public static void println(HandlerContext context) { + String value = (String) context.getInputValue("value"); + System.out.println(value); + } + + /** + *

    This handler writes using + * FacesContext.getResponseWriter().

    + * + * @param context The HandlerContext. + */ + @Handler(id="write", + input={@HandlerInput(name="value", type=String.class, required=true)}) + public static void write(HandlerContext context) { + String text = (String) context.getInputValue("value"); + if (text == null) { + // Even though this is required, an expression can evaluate to null + text = ""; + } + try { + context.getFacesContext().getResponseWriter().write(text); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + + /** + *

    This handler decrements a number by 1. This handler requires + * "number" to be supplied as an Integer input value. It sets an + * output value "value" to number-1.

    + * + * @param context The HandlerContext. + */ + @Handler(id="dec", + input={ + @HandlerInput(name="number", type=Integer.class, required=true)}, + output={ + @HandlerOutput(name="value", type=Integer.class)}) + public static void dec(HandlerContext context) { + Integer value = (Integer) context.getInputValue("number"); + context.setOutputValue("value", new Integer(value.intValue() - 1)); + } + + /** + *

    This handler increments a number by 1. This handler requires + * "number" to be supplied as an Integer input value. It sets an + * output value "value" to number+1.

    + * + * @param context The HandlerContext. + */ + @Handler(id="inc", + input={ + @HandlerInput(name="number", type=Integer.class, required=true)}, + output={ + @HandlerOutput(name="value", type=Integer.class)}) + public static void inc(HandlerContext context) { + Integer value = (Integer) context.getInputValue("number"); + context.setOutputValue("value", new Integer(value.intValue() + 1)); + } + + /** + *

    This method returns an Iterator for the given + * List. The List input value key is: + * "list". The output value key for the Iterator is: + * "iterator".

    + * + * @param context The HandlerContext. + */ + @Handler(id="getIterator", + input={ + @HandlerInput(name="list", type=List.class, required=true)}, + output={ + @HandlerOutput(name="iterator", type=Iterator.class)}) + public static void getIterator(HandlerContext context) { + List list = (List) context.getInputValue("list"); + context.setOutputValue("iterator", list.iterator()); + } + + /** + *

    This method returns a Boolean value representing + * whether another value exists for the given Iterator. + * The Iterator input value key is: "iterator". The + * output value key is "hasNext".

    + * + * @param context The HandlerContext. + */ + @Handler(id="iteratorHasNext", + input={ + @HandlerInput(name="iterator", type=Iterator.class, required=true)}, + output={ + @HandlerOutput(name="hasNext", type=Boolean.class)}) + public static void iteratorHasNext(HandlerContext context) { + Iterator it = (Iterator) context.getInputValue("iterator"); + context.setOutputValue("hasNext", Boolean.valueOf(it.hasNext())); + } + + /** + *

    This method returns the next object in the List that + * the given Iterator is iterating over. The + * Iterator input value key is: "iterator". The + * output value key is "next".

    + * + * @param context The HandlerContext. + */ + @Handler(id="iteratorNext", + input={ + @HandlerInput(name="iterator", type=Iterator.class, required=true)}, + output={ + @HandlerOutput(name="next")}) + public static void iteratorNext(HandlerContext context) { + Iterator it = + (Iterator) context.getInputValue("iterator"); + context.setOutputValue("next", it.next()); + } + + /** + *

    This method creates a List. Optionally you may supply "size" to + * create a List of blank "" values of the specified size. The + * output value from this handler is "result".

    + * + * @param context The HandlerContext + */ + @Handler(id="createList", + input={ + @HandlerInput(name="size", type=Integer.class, required=true)}, + output={ + @HandlerOutput(name="result", type=List.class)}) + public static void createList(HandlerContext context) { + int size = ((Integer) context.getInputValue("size")).intValue(); + List list = new ArrayList(size); + for (int count = 0; count < size; count++) { + list.add(""); + } + context.setOutputValue("result", list); + } + + /** + *

    This method creates a Map (HashMap). + * The output value from this handler is "result".

    + * + * @param context The HandlerContext + */ + @Handler(id="createMap", + output={ + @HandlerOutput(name="result", type=Map.class)}) + public static void createMap(HandlerContext context) { + Map map = new HashMap(); + context.setOutputValue("result", map); + } + + /** + *

    This method adds a value to a Map. You must supply + * map to use as well as the key and + * value to add.

    + * + * @param context The HandlerContext + */ + @Handler(id="mapPut", + input={ + @HandlerInput(name="map", type=Map.class, required=true), + @HandlerInput(name="key", type=Object.class, required=true), + @HandlerInput(name="value", type=Object.class, required=true)} + ) + public static void mapPut(HandlerContext context) { + Map map = (Map) context.getInputValue("map"); + Object key = context.getInputValue("key"); + Object value = context.getInputValue("value"); + map.put(key, value); + } + + /** + *

    This method returns true. It does not take any input or provide + * any output values.

    + * + * @param context The {@link HandlerContext} + */ + @Handler(id="returnTrue") + public static boolean returnTrue(HandlerContext context) { + return true; + } + + /** + *

    This method returns false. It does not take any input or provide + * any output values.

    + * + * @param context The {@link HandlerContext} + */ + @Handler(id="returnFalse") + public static boolean returnFalse(HandlerContext context) { + return false; + } + + /** + *

    This method enables you to retrieve the clientId for the given + * UIComponent.

    + * + * @param context The {@link HandlerContext} + */ + @Handler(id="getClientId", + input={ + @HandlerInput(name="component", type=UIComponent.class, required=true)}, + output={ + @HandlerOutput(name="clientId", type=String.class)}) + public static void getClientId(HandlerContext context) { + UIComponent comp = (UIComponent) context.getInputValue("component"); + context.setOutputValue("clientId", + comp.getClientId(context.getFacesContext())); + } + + /** + *

    This method enables you to retrieve the id or clientId for the given + * Object which is expected to be a + * UIComponent or a String that already + * represents the clientId.

    + * + * @param context The {@link HandlerContext} + */ + @Handler(id="getId", + input={ + @HandlerInput(name="object", required=true)}, + output={ + @HandlerOutput(name="id", type=String.class), + @HandlerOutput(name="clientId", type=String.class)}) + public static void getId(HandlerContext context) { + Object obj = context.getInputValue("object"); + if (obj == null) { + return; + } + + String clientId = null; + String id = null; + if (obj instanceof UIComponent) { + clientId = + ((UIComponent) obj).getClientId(context.getFacesContext()); + id = ((UIComponent) obj).getId(); + } else { + clientId = obj.toString(); + id = clientId.substring(clientId.lastIndexOf(':') + 1); + } + context.setOutputValue("id", id); + context.setOutputValue("clientId", clientId); + } + + /** + *

    This handler provides a way to see the call stack by printing a + * stack trace. The output will go to stderr and will also be + * returned in the output value "stackTrace". An optional message + * may be provided to be included in the trace.

    + * + * @param context The HandlerContext. + */ + @Handler(id="printStackTrace", + input={ + @HandlerInput(name="msg", type=String.class)}, + output={ + @HandlerOutput(name="stackTrace", type=String.class)}) + public static void printStackTrace(HandlerContext context) { + // See if we have a message to print w/ it + String msg = (String) context.getInputValue("msg"); + if (msg == null) { + msg = ""; + } + + // Get the StackTrace + StringWriter strWriter = new StringWriter(); + new RuntimeException(msg).printStackTrace(new PrintWriter(strWriter)); + String trace = strWriter.toString(); + + // Print it to stderr and return it + System.err.println(trace); + context.setOutputValue("stackTrace", trace); + } + + /** + *

    This handler prints out the contents of the given UIComponent's + * attribute map.

    + * + * @param context The HandlerContext. + */ + @Handler(id="dumpAttributeMap", + input={ + @HandlerInput(name="component", type=UIComponent.class)}) + public static void dumpAttributeMap(HandlerContext context) { + UIComponent comp = (UIComponent) context.getInputValue("component"); + if (comp != null) { + Map map = comp.getAttributes(); + for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { + Map.Entry me = (Map.Entry)iter.next(); + System.out.println("key="+ me.getKey()+"'"+"value="+ me.getValue()); + } + } else { + System.out.println("UIComponent is null"); + + } + } + + /** + *

    This handler sets the encoding type of the given UIViewRoot's + * attribute map.

    + * + * @param context The HandlerContext. + */ + @Handler(id="setEncoding", + input={ + @HandlerInput(name="value", type=String.class) + }) + public static void setEncoding(HandlerContext context) { + String value = (String) context.getInputValue("value"); + FacesContext fctxt = context.getFacesContext(); + if(fctxt != null) { + UIViewRoot root = fctxt.getViewRoot(); + // Get the Page Session Map + Map map = + PageSessionResolver.getPageSession(fctxt, root); + if (map == null) { + map = PageSessionResolver.createPageSession(fctxt, root); + } + + // Set the page session value + map.put(LayoutViewHandler.ENCODING_TYPE , value); + } + } + + /** + *

    This handler url encodes the given String. It will return null if + * null is given and it will use a default encoding of "UTF-8" if no + * encoding is specified.

    + * + * @param context The HandlerContext. + */ + @Handler(id="urlencode", + input={ + @HandlerInput(name="value", type=String.class, required=true), + @HandlerInput(name="encoding", type=String.class) + }, + output={ + @HandlerOutput(name="result", type=String.class)}) + public static void urlencode(HandlerContext context) { + String value = (String) context.getInputValue("value"); + String encoding = (String) context.getInputValue("encoding"); + if (encoding == null) { + encoding = "UTF-8"; + } + // The value could be null if an EL expression maps to null + if (value != null) { + try { + value = URLEncoder.encode(value, encoding); + } catch (UnsupportedEncodingException ex) { + throw new IllegalArgumentException(ex); + } + } + context.setOutputValue("result", value); + } + + /** + *

    This handler marks the response complete. This means that no + * additional response will be sent. This is useful if you've + * provided a response already and you don't want JSF to do it again + * (it may cause problems to do it 2x).

    + * + * @param context The HandlerContext. + */ + @Handler(id="responseComplete") + public static void responseComplete(HandlerContext context) { + context.getFacesContext().responseComplete(); + } + + /** + *

    This handler indicates to JSF that the request should proceed + * immediately to the render response phase. It will be ignored if + * rendering has already begun. This is useful if you want to stop + * processing and jump to the response. This is often the case when + * an error ocurrs or validation fails. Typically the page the user + * is on will be reshown (although if navigation has already + * occurred, the new page will be shown.

    + * + * @param context The HandlerContext. + */ + @Handler(id="renderResponse") + public static void renderResponse(HandlerContext context) { + context.getFacesContext().renderResponse(); + } + + /** + *

    This handler gets the current system time in milliseconds. It may + * be used to time things.

    + */ + @Handler(id="getDate", + output={ + @HandlerOutput(name="time", type=Long.class) + }) + public static void getDate(HandlerContext context) { + context.setOutputValue("time", new java.util.Date().getTime()); + } + + /** + *

    This method converts '<' and '>' characters into "&lt;" + * and "&gt;" in an effort to avoid HTML from being processed. + * This can be used to avoid <script> tags, or to show code + * examples which might include HTML characters. '&' characters + * will also be converted to "&amp;".

    + */ + @Handler(id="htmlEscape", + input={ + @HandlerInput(name="value", type=String.class, required=true) + }, + output={ + @HandlerOutput(name="result", type=String.class)}) + public static void htmlEscape(HandlerContext context) { + String value = (String) context.getInputValue("value"); + value = Util.htmlEscape(value); + context.setOutputValue("result", value); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutDefinitionException.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutDefinitionException.java new file mode 100644 index 0000000..eeed98f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutDefinitionException.java @@ -0,0 +1,66 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout; + +import com.sun.jsftemplating.TemplatingException; + + +/** + *

    This exception is thrown when a {@link LayoutDefinitionManager} is + * unable to locate a + * {@link com.sun.jsftemplating.layout.descriptors.LayoutDefinition}. + * This exception should not be used to indicate that a syntax error has + * occurred, see {@link SyntaxException}. This exception is meant for + * file not found, i/o problems, etc.

    + */ +public class LayoutDefinitionException extends TemplatingException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public LayoutDefinitionException(String msg, Throwable ex) { + super(msg, ex); + } + + /** + * + */ + public LayoutDefinitionException() { + super(); + } + + /** + * + */ + public LayoutDefinitionException(Throwable ex) { + super(ex); + } + + /** + * + */ + public LayoutDefinitionException(String msg) { + super(msg); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutDefinitionManager.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutDefinitionManager.java new file mode 100644 index 0000000..606759e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutDefinitionManager.java @@ -0,0 +1,1194 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout; + +import com.sun.jsftemplating.annotation.FormatDefinitionAP; +import com.sun.jsftemplating.annotation.HandlerAP; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.UIComponentFactoryAP; +import com.sun.jsftemplating.component.factory.basic.GenericFactory; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutComposition; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.LayoutInsert; +import com.sun.jsftemplating.layout.descriptors.Resource; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition; +import com.sun.jsftemplating.layout.descriptors.handler.IODescriptor; +import com.sun.jsftemplating.layout.facelets.DbFactory; +import com.sun.jsftemplating.layout.facelets.NSContext; +import com.sun.jsftemplating.layout.template.TemplateLayoutDefinitionManager; +import com.sun.jsftemplating.util.FileUtil; +import com.sun.jsftemplating.util.LogUtil; +import com.sun.jsftemplating.util.Util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.InvocationTargetException; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.faces.context.FacesContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + *

    This abstract class provides the base functionality for all + * LayoutDefinitionManager implementations. It provides a + * static method used to obtain an instance of a concrete + * LayoutDefinitionManager: + * {@link #getLayoutDefinitionManager(FacesContext,String)}. However, in + * most cases is makes the most sense to call the static method: + * {@link #getLayoutDefinition(FacesContext,String)}. This method + * ensures that the cache is checked first before going through the effort + * of finding a LayoutDefinitionManager instance.

    + * + *

    This class also provides access to global {@link HandlerDefinition}s, + * {@link Resource}s, and {@link ComponentType}s.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public abstract class LayoutDefinitionManager { + + /** + *

    Constructor.

    + */ + protected LayoutDefinitionManager() { + super(); + } + + /** + *

    This method is responsible for finding/creating the requested + * {@link LayoutDefinition}.

    + * + * @param key The key used to identify the requested + * {@link LayoutDefinition}. + */ + public abstract LayoutDefinition getLayoutDefinition(String key) throws LayoutDefinitionException; + + /** + *

    This method is used to determine if this + * LayoutDefinitionManager should process the given key. + * It does not necessarily mean that the + * LayoutDefinitionManager can process it. + * Parser errors do not necessarily mean that it should not process + * the file. In order to provide meaningful error messages, this + * method should return true if the format of the template matches the + * type that this LayoutDefinitionManager processes. It + * is understood that at times it may not be recognizable; in the case + * where no LayoutDefinitionManagers return + * true from this method, the parent + * ViewHandler will be used, which likely means that it + * will look for a .jsp and give error messages accordingly. Also, + * the existance of a file should not be used as a meassure of success + * as other LayoutDefinitionManagers may be more + * appropriate.

    + */ + public abstract boolean accepts(String key); + + /** + *

    This method should be used to obtain a {@link LayoutDefinition}. + * It first checks to see if a cached {@link LayoutDefinition} + * already exists, if so it returns it. If one does not already + * exist, it will obtain the appropriate + * LayoutDefinitionManager instance and call + * {@link #getLayoutDefinition} and return the result.

    + */ + public static LayoutDefinition getLayoutDefinition(FacesContext ctx, String key) throws LayoutDefinitionException { + // Determine the key we should use to cache this + String cacheKey = FileUtil.cleanUpPath(key.startsWith("/") ? + key : FileUtil.getAbsolutePath(ctx, key)); + + // Check to see if we already have it. + LayoutDefinition def = getCachedLayoutDefinition(ctx, cacheKey); +//System.out.println("GET LD (" + cacheKey + ", " + isDebug(ctx) + "):" + def); + if (def == null) { + // Obtain the correct LDM, and get the LD + def = getLayoutDefinitionManager(ctx, key).getLayoutDefinition(key); +//System.out.println(" Found LD (" + cacheKey + ")?:" + def); + putCachedLayoutDefinition(ctx, cacheKey, def); + } else { + // In the case where we found a cached version, + // ensure we invoke "initPage" handlers + def.dispatchInitPageHandlers(ctx, def); + } +// FIXME: Flag a page as *not found* for performance reasons when JSP is used (or other view technologies) + + // Return the LD + return def; + } + + /** + *

    This method finds the (closest) requested + * LayoutComponent for the given clientId. + * If the viewId is not supplied, the current + * UIViewRoot will be used. If an exact match is not + * found, it will return the last {@link LayoutComponent} found while + * walking the tree -- this represents the last {@link LayoutComponent} + * in the hierarchy of the specified component. If nothing matches the + * given clientId, null will be returned.

    + * + *

    This is not an easy process since JSF components are not all + * NamingContainers, so the clientId is not + * sufficient to find it. This is unfortunate, but we we deal with + * it.

    + * + * @param ctx The FacesContext. + * @param ldKey The {@link LayoutDefinition} key to identify the + * {@link LayoutDefinition} tree to be searched. + * @param clientId The component clientId for which to + * obtain a {@link LayoutComponent}. + */ + public static LayoutComponent getLayoutComponent(FacesContext ctx, String ldKey, String clientId) throws LayoutDefinitionException { + // Find the page first... + LayoutElement layElt = null; + if (ldKey != null) { +// FIXME: This fixme probably belongs in getLD(ctx, key): initPage should only be invoked if the page is accessed for the first time on the request. This potentially calls it multiple times. + layElt = getLayoutDefinition(ctx, ldKey); + if (layElt == null) { + throw new LayoutDefinitionException( + "Unable to find LayoutDefinition ('" + ldKey + "')"); + } + } else { + layElt = ViewRootUtil.getLayoutDefinition( + FacesContext.getCurrentInstance().getViewRoot()); + } + + // Save the current LayoutComposition Stack + // - This is needed b/c we may be in the middle of walking the tree + // - already and we need ot use this Stack... so we must save the + // - Stack and use a fresh one. We must restore it later. + Stack oldStack = LayoutComposition.getCompositionStack(ctx); + try { + LayoutComposition.setCompositionStack( + ctx, new Stack()); + + // Create a StringTokenizer over the clientId + StringTokenizer tok = new StringTokenizer(clientId, ":"); + + // Walk the LD looking for the individual id's specified in the + // clientId. + String id = null; + LayoutElement match = null; + while (tok.hasMoreTokens()) { + // I don't want to create a bunch of objects to check for + // instanceof NamingContainer. I can't check the class file + // b/c there is no way for me to know what class gets created + // before actually creating the UIComponent. This is because + // either the ComponentFactory can decide how to create the + // UIComponent, which it often uses the Application. The + // Application is driven off the faces-config.xml file(s). + // + // I will instead do a brute force search for a match. This + // has the potential to fail if non-naming containers have the + // same id's as naming containers. It may also fail for + // components with dynamic id's. + id = tok.nextToken(); + match = findById(ctx, layElt, id); + if (match == null) { + // Can't go any further! We're as close as we're getting. + break; + } + layElt = match; + } + } finally { + // Restore the previous LayoutComposition Stack + LayoutComposition.setCompositionStack(ctx, oldStack); + } + + // Make sure we're not still at the LayoutDefinition, if so do NOT + // accept this as a match. + if (layElt instanceof LayoutDefinition) { + layElt = null; + } + + // Return the closest match (or null if nothing found) + return (LayoutComponent) layElt; + } + + /** + *

    This method performs a breadth-first search for a child + * {@link LayoutComponent} with the given id of the given + * {@link LayoutElement} (elt). It will return null if + * none of the children (or children's children, etc.) equal the given + * id.

    + */ + private static LayoutComponent findById(FacesContext ctx, LayoutElement elt, String id) { + boolean shouldPop = false; + + // Check for special LE's + if (elt instanceof LayoutComposition) { + // We have a LayoutComposition, this includes another file... we + // need to look there as well. + String viewId = ((LayoutComposition) elt).getTemplate(); + if (viewId != null) { + // Add LayoutComposition to the stack + LayoutComposition.push(ctx, elt); + shouldPop = true; + + // Get the new LD to walk + try { + elt = LayoutDefinitionManager.getLayoutDefinition(ctx, viewId); + } catch (LayoutDefinitionException ex) { + if (((LayoutComposition) elt).isRequired()) { + throw ex; + } + } + } + } else if (elt instanceof LayoutInsert) { + // We found a LayoutInsert, this includes content from a previous + // file... we need to go back there and look now. + } + + // First search the direct child LayoutElement + LayoutComponent comp = null; + for (LayoutElement child : elt.getChildLayoutElements()) { + // I am *NOT* providing the parent UIComponent as it may not be + // available, this function is *not* guaranteed to work for + // dynamic ids + if (child.getId(ctx, null).equals(id) + && (child instanceof LayoutComponent)) { + // Found it! + comp = (LayoutComponent) child; + } + } + + // Not found directly under it, search children... + // NOTE: Must do a breadth first search, so 2 loops are necessary + if (comp == null) { + for (LayoutElement child : elt.getChildLayoutElements()) { + comp = findById(ctx, child, id); + if (comp != null) { + // Found it! + break; + } + } + } + + // Remove the LayoutComposition from the stack + if (shouldPop) { + LayoutComposition.pop(ctx); + } + + // Return the result, or null if not found + return comp; + } + + /** + *

    This method obtains the LayoutDefinitionManager that + * is able to process the given key.

    + * + *

    This implementation uses the ExternalContext's + * initParams to look for the LayoutDefinitionManager + * class. If it exists, the specified concrete + * LayoutDefinitionManager class will be used as the + * "default" (i.e. the first LayoutDefinitionManager + * checked). "{@link #LAYOUT_DEFINITION_MANAGER_KEY}" is the + * initParam key.

    + * + *

    The key is used to test if desired + * LayoutDefinitionManager is able to read the requested + * {@link LayoutDefinition}.

    + * + * @param ctx The FacesContext. + * @param key The desired {@link LayoutDefinition}. + * @see #LAYOUT_DEFINITION_MANAGER_KEY + */ + public static LayoutDefinitionManager getLayoutDefinitionManager(FacesContext ctx, String key) throws LayoutDefinitionException { + List ldms = getLayoutDefinitionManagers(ctx); +//System.out.println("LDMS: " + ldms); + LayoutDefinitionManager mgr = null; + for (String className : ldms) { + mgr = getLayoutDefinitionManagerByClass(ctx, className); +//System.out.println("LDM ("+className+"): " + mgr); + if (mgr.accepts(key)) { +//System.out.println("Accepts!"); + return mgr; + } + } + throw new LayoutDefinitionException("No LayoutDefinitionManager " + + "available for '" + key + "'. This may mean the file cannot " + + "be found, or is unrecognizable."); + } + + /** + *

    This method is responsible for returning a List of + * known LayoutDefinitionManager instances. Each value + * of the list is a String representing the classname of + * a LayoutDefinitionManager implementation.

    + */ + public static List getLayoutDefinitionManagers(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + List keys = null; + if (ctx != null) { + keys = (List) ctx.getExternalContext(). + getApplicationMap().get(LDM_KEYS); + } + if (keys == null) { + // 1st time... initialize it + keys = new ArrayList(); + + // Check to see what the default should be... + if (ctx != null) { + Map initParams = ctx.getExternalContext().getInitParameterMap(); + if (initParams.containsKey(LAYOUT_DEFINITION_MANAGER_KEY)) { + keys.add(((String) initParams. + get(LAYOUT_DEFINITION_MANAGER_KEY)).trim()); + } + } + + // Make "template" format the default (if none specified) + String tplFormat = TemplateLayoutDefinitionManager.class.getName(); + if (!keys.contains(tplFormat)) { + keys.add(tplFormat); + } + + try { + // Get all the files that define them + BufferedReader rdr = null; + InputStream is = null; + String line = null; + Enumeration urls = Util.getClassLoader(ctx). + getResources(FormatDefinitionAP.FACTORY_FILE); + while (urls.hasMoreElements()) { + // Add all lines in each file to the list of LDMs + try { + is = urls.nextElement().openStream(); + rdr = new BufferedReader(new InputStreamReader(is)); + for (line = rdr.readLine(); line != null; line = rdr.readLine()) { + line = line.trim(); + + if (line.equals("") || line.startsWith("#")) { + // Skip comments + continue; + } + if (keys.contains(line)) { + // Skip ones already added... + continue; + } + + // Add it! + keys.add(line); + } + } finally { + Util.closeStream(is); + } + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + if (ctx != null) { + // Save the result in Application Scope + ctx.getExternalContext().getApplicationMap(). + put(LDM_KEYS, keys); + } + } + + // Return the LDM keys + return keys; + } + + /** + *

    This method is a singleton factory method for obtaining an instance + * of a LayoutDefintionManager. It is possible that + * multiple different implementations of + * LayoutDefinitionManagers will be used within the same + * application. This is OK. Someone may provide a different + * LayoutDefinitionManager to locate + * {@link LayoutDefinition}'s in a different way (XML, database, file, + * java code, new file format, etc.).

    + */ + public static LayoutDefinitionManager getLayoutDefinitionManagerByClass(FacesContext ctx, String className) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Map ldms = null; + if (ctx != null) { + ldms = (Map) + ctx.getExternalContext().getApplicationMap().get(LDMS); + } + if (ldms == null) { + ldms = new HashMap(4); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put(LDMS, ldms); + } + } + LayoutDefinitionManager ldm = ldms.get(className); + if (ldm == null) { + try { + ldm = (LayoutDefinitionManager) + Util.loadClass(className, className). + getMethod("getInstance", (Class[]) null). + invoke((Object) null, (Object[]) null); + } catch (ClassNotFoundException ex) { + throw new LayoutDefinitionException( + "Unable to find LDM: '" + className + "'.", ex); + } catch (NoSuchMethodException ex) { + throw new LayoutDefinitionException("LDM '" + className + + "' does not have a 'getInstance()' method!", ex); + } catch (IllegalAccessException ex) { + throw new LayoutDefinitionException("Unable to access LDM: '" + + className + "'!", ex); + } catch (InvocationTargetException ex) { + throw new LayoutDefinitionException("Error while attempting " + + "to get LDM: '" + className + "'!", ex); + } catch (ClassCastException ex) { + throw new LayoutDefinitionException("LDM '" + className + + "' must extend from '" + + LayoutDefinitionManager.class.getName() + " and must " + + "be loaded from the same ClassLoader!", ex); + } catch (NullPointerException ex) { + throw new LayoutDefinitionException(ex); + } + ldms.put(className, ldm); + } + return ldm; + } + + /** + *

    This method may be used to obtain a cached + * {@link LayoutDefinition}. If it has not been cached, this method + * returns null.

    + * + * @param ctx The FacesContext. + * @param key Key for the cached {@link LayoutDefinition} to obtain. + * + * @return The {@link LayoutDefinition} or null. + */ + private static LayoutDefinition getCachedLayoutDefinition(FacesContext ctx, String key) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + if (isDebug(ctx)) { + if (ctx != null) { + // Make sure we cache during the life of the request, even + // in Debug mode + return (LayoutDefinition) ctx.getExternalContext(). + getRequestMap().get(CACHE_PREFIX + key); + } + + // Disable caching for debug mode + return null; + } + + return getLayoutDefinitionMap(ctx).get(key); + } + + /** + *

    This method returns the LD Map which is stored in application + * scope. If it has not been created yet, it will be created as a + * ConcurrentHashMap

    . + */ + private static Map getLayoutDefinitionMap(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Map ldMap = null; + if (ctx != null) { + ldMap = (Map) + ctx.getExternalContext().getApplicationMap().get(LD_MAP); + } + if (ldMap == null) { + // 1st time... initialize it + // Consider using a SoftReference here... + ldMap = new ConcurrentHashMap( + 400, 0.75f, 2); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put(LD_MAP, ldMap); + } + } + + // Return the map... + return ldMap; + } + + /** + *

    In general, this method should be used by sub-classes to store a + * cached {@link LayoutDefinition}. It may also be used, however, to + * define {@link LayoutDefinition}s on the fly (not recommended unless + * you know what you're doing. ;)

    + * + * @param ctx The FacesContext. + * @param key The {@link LayoutDefinition} key to cache. + * @param value The {@link LayoutDefinition} to cache. + */ + public static void putCachedLayoutDefinition(FacesContext ctx, String key, LayoutDefinition value) { +//System.out.println("CACHING LD: " + key); + if (isDebug(ctx)) { + if (ctx != null) { + // Make sure we cache during the life of the request, even + // in Debug mode + ctx.getExternalContext().getRequestMap(). + put(CACHE_PREFIX + key, value); + } + } else { + getLayoutDefinitionMap(ctx).put(key, value); + } + } + + /** + *

    Retrieve an attribute by key.

    + * + * @param key The key used to retrieve the attribute. + * + * @return The requested attribute or null + */ + public Object getAttribute(String key) { + return _attributes.get(key); + } + + + /** + *

    Associate the given key with the given Object as an attribute.

    + * + * @param key The key associated with the given object (if this key + * is already in use, it will replace the previously set + * attribute object). + * @param value The Object to store. + */ + public void setAttribute(String key, Object value) { + _attributes.put(key, value); + } + + /** + *

    This method returns the Map of global + * {@link ComponentType}s (the {@link ComponentType}s available across + * the application).

    + * + *

    It is recommended that this method not be used directly. The map + * returned by this method is shared across the application and is not + * thread safe. Instead access this Map via + * {@link LayoutDefinitionManager#getGlobalComponentType(FacesContext, String)}.

    + * + *

    This method will initialize the global {@link ComponentType}s if + * they are not initialized. It does this by finding all files in the + * classpath named: + * {@link UIComponentFactoryAPFactory#FACTORY_FILE}. It then reads + * each of these files (which must be Properties files) + * and stores each identifier / fully qualified classname as an entry + * in the Map<String, {@link ComponentType}>.

    + * + * @param ctx The FacesContext. + */ + public static Map getGlobalComponentTypes(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Map types = null; + if (ctx != null) { + types = (Map) ctx.getExternalContext(). + getApplicationMap().get(CT_MAP); + } + if (types == null) { + // We haven't initialized the global ComponentTypes yet... + types = new ConcurrentHashMap(200, 0.75f, 2); + try { + Properties props = null; + URL url = null; + String id = null; + // Get all the properties files that define them + Enumeration urls = + Util.getClassLoader(types). + getResources(UIComponentFactoryAP.FACTORY_FILE); + while (urls.hasMoreElements()) { + url = urls.nextElement(); + props = new Properties(); + // Load each Properties file + InputStream is = null; + try { + is = url.openStream(); + props.load(is); + for (Map.Entry entry : props.entrySet()) { + // Add each property entry (key, ComponentType) + id = (String) entry.getKey(); + types.put(id, new ComponentType(id, (String) entry.getValue())); + } + } finally { + Util.closeStream(is); + } + } + readComponentsFromTaglibXml(types); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + // Save it for next time... + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put(CT_MAP, types); + } + } + + // Return all the global ComponentTypes + return types; + } + + private static void readComponentsFromTaglibXml(Map types) throws IOException { + Enumeration urls = Util.getClassLoader(types).getResources("META-INF/"); + Set files = new HashSet(); + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + URLConnection conn = url.openConnection(); + conn.setUseCaches(false); + conn.setDefaultUseCaches(false); + + if (conn instanceof JarURLConnection) { + JarURLConnection jarConn = (JarURLConnection) conn; + JarFile jarFile = jarConn.getJarFile(); + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + if (entryName.startsWith("META-INF") && entryName.endsWith("taglib.xml")) { + Enumeration e = Util.getClassLoader(types).getResources(entryName); + while (e.hasMoreElements()) { + files.add(e.nextElement()); + } + } + } + } else { + // TODO: I have yet to hit this branch +// File dir = new File(url.getFile()); +// String fileList[] = dir.list(new FilenameFilter() { +// public boolean accept(File file, String fileName) { +// return fileName.endsWith("taglib.xml"); +// } }); + } + + } + if(files.size() >0) { + for (URL url : files) { + processTaglibXml(url, types); + } + } + } + + private static void processTaglibXml(URL url, Map types) { + InputStream is = null; + try { + is = url.openStream(); + DocumentBuilder builder = DbFactory.getInstance(); + Document document = builder.parse(is); + XPath xpath = XPathFactory.newInstance().newXPath(); + NSContext ns = new NSContext(); + ns.addNamespace("f", "http://java.sun.com/JSF/Facelet"); + // Although the following should work, XPath doesn't attempt to + // get the namespace when no namespace is supplied. + //ns.setDefaultNSURI("http://java.sun.com/JSF/Facelet"); + xpath.setNamespaceContext(ns); + + String nameSpace = xpath.evaluate("/f:facelet-taglib/f:namespace", document); + + // Process elements + NodeList nl = (NodeList) xpath.evaluate("/f:facelet-taglib/f:tag", document, XPathConstants.NODESET); + for (int i = 0; i < nl.getLength(); i++) { + Node node = nl.item(i); + String tagName = xpath.evaluate("f:tag-name", node); + String componentType = xpath.evaluate("f:component/f:component-type", node); + String id = nameSpace + ":" + tagName; + types.put(id, + new ComponentType(id, GenericFactory.class.getName(), componentType)); + } + } catch (Exception e) { + if (LogUtil.severeEnabled()) { + LogUtil.severe(e.getMessage()); + } + throw new RuntimeException(e); + } finally { + Util.closeStream(is); + } + } + + /** + *

    This method retrieves a globally defined {@link ComponentType} (a + * {@link ComponentType} available across the application).

    + */ + public static ComponentType getGlobalComponentType(FacesContext ctx, String typeID) { + return getGlobalComponentTypes(ctx).get(typeID); + } + + /** + *

    This method allows a global {@link ComponentType} to be added. + * This way of adding a global {@link ComponentType} is discouraged. + * Instead, you should use a UIComponentFactory + * annotation in each ComponentFactory and compile + * using "apt".

    + */ + public static void addGlobalComponentType(FacesContext ctx, ComponentType type) { + getGlobalComponentTypes(ctx).put(type.getId(), type); + } + + /** + *

    This method clears the cached global {@link ComponentType}s.

    + */ + public static void clearGlobalComponentTypes(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().remove(CT_MAP); + } + } + + /** + *

    This method returns the Map of global + * {@link HandlerDefinition}s (the {@link HandlerDefinition}s + * available across the application).

    + * + *

    It is recommended that this method not be used. The map returned + * by this method is shared across the application and is not thread + * safe. Instead get values from the Map via: + * {@link LayoutDefinitionManager#getGlobalHandlerDefinition(String)}. + *

    + * + *

    This method will initialize the global {@link HandlerDefinition}s if + * they are not initialized. It does this by finding all files in the + * classpath named: {@link HandlerAPFactory#HANDLER_FILE}. It then + * reads each file (which must be a valid Properties + * file) and stores the information for later retrieval.

    + */ + public static Map getGlobalHandlerDefinitions() { + return getGlobalHandlerDefinitions(HandlerAP.HANDLER_FILE); + } + + /** + *

    This method is the same as {@link #getGlobalHandlerDefinitions()}, + * however, it accepts the full name of the Handler.map + * to use. This allows different filenames to be used. It will only + * read the same filename one time, however, it will read + * all occurances of that file name (it calls + * ClassLoader.getResources(filename)

    + */ + public synchronized static Map getGlobalHandlerDefinitions(String filename) { + Map handlers = getApplicationHandlerDefinitions(null); + if (handlers.containsKey(filename)) { + // We've already done this, return the answer + return handlers; + } + + // Copy the old ones while we modify it... + handlers = new HashMap(handlers); + + // Add the 'filename' key as a flag that we've processed these + handlers.put(filename, NOOP_HD); + + Properties props = null; + URL url = null; + try { + // Get all the properties files that define them + Enumeration urls = Util.getClassLoader(filename). + getResources(filename); + InputStream is = null; + while (urls.hasMoreElements()) { + try { + url = urls.nextElement(); + props = new Properties(); + // Load each Properties file + is = url.openStream(); + props.load(is); + for (Map.Entry entry : props.entrySet()) { + if (((String) entry.getKey()).endsWith(".class")) { + // We will only process .class entries. + readGlobalHandlerDefinition(handlers, + (Map) props, entry); + } + } + } finally { + Util.closeStream(is); + } + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + // Store the results in application scope... + FacesContext ctx = FacesContext.getCurrentInstance(); + ctx.getExternalContext().getApplicationMap().put(HD_MAP, handlers); + + // return the complete Map + return handlers; + } + + /** + *

    This method returns the current application's + * {@link HandlerDefinition} Map.

    + */ + private static Map getApplicationHandlerDefinitions(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Map map = null; + if (ctx != null) { + map = (Map) ctx.getExternalContext(). + getApplicationMap().get(HD_MAP); + } + if (map == null) { + // Initialize it... + map = new HashMap(); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put(HD_MAP, map); + } + } + + return map; + } + + /** + *

    This method processes a single {@link HandlerDefinition}'s + * meta-data.

    + */ + private static void readGlobalHandlerDefinition(Map hdMap, Map props, Map.Entry entry) { + // Get the key.class value... + String key = (String) entry.getKey(); + // Strip off .class + key = key.substring(0, key.lastIndexOf('.')); + + // Create a new HandlerDefinition + HandlerDefinition def = new HandlerDefinition(key); + + // Set the class / method + String value = props.get(key + '.' + "method"); + def.setHandlerMethod((String) entry.getValue(), value); + + // Read the input defs + def.setInputDefs(readIODefs(props, key, true)); + + // Read the output defs + def.setOutputDefs(readIODefs(props, key, false)); + + // Add the Handler... + hdMap.put(key, def); + } + + /** + *

    This method reads and creates IODescriptors for the given key.

    + */ + private static Map readIODefs(Map map, String key, boolean input) { + String type; + String inOrOut = input ? "input" : "output"; + int count = 0; + IODescriptor desc = null; + Map defs = new HashMap(5); + String value = map.get(key + "." + inOrOut + "[" + count + "].name"); + while (value != null) { + // Get the type + type = map.get(key + "." + inOrOut + "[" + count + "].type"); + if (type == null) { + type = DEFAULT_TYPE; + } + + // Create an IODescriptor + desc = new IODescriptor(value, type); + defs.put(value, desc); + + // If this is an output, we're done... for input we need to do more + if (input) { + // required? + value = map.get(key + "." + inOrOut + "[" + count + "].required"); + if ((value != null) && Boolean.valueOf(value).booleanValue()) { + desc.setRequired(true); + } + + // default? + value = map.get(key + "." + inOrOut + "[" + count + "].defaultValue"); + if ((value != null) && !value.equals(HandlerInput.DEFAULT_DEFAULT_VALUE)) { + desc.setDefault(value); + } + } + + // Look for next IO declaration + value = map.get(key + "." + inOrOut + "[" + (++count) + "].name"); + } + + return defs; + } + + /** + *

    This method retrieves a globally defined {@link HandlerDefinition} (a + * {@link HandlerDefinition} available across the application).

    + */ + public static HandlerDefinition getGlobalHandlerDefinition(String id) { + return getGlobalHandlerDefinitions().get(id); + } + + /** + *

    This method allows a global {@link HandlerDefinition} to be added. + * This way of adding a global {@link HandlerDefinition} is + * discouraged. It should be done implicitly through annotations, + * placement of a properties file in the correct location, or + * explicitly by declaring it the page (some template formats may not + * support this).

    + * + * @see LayoutDefinitionManager#getGlobalHandlerDefinitions() + */ + public static void addGlobalHandlerDefinition(HandlerDefinition def) { + synchronized (LayoutDefinitionManager.class) { + getGlobalHandlerDefinitions().put(def.getId(), def); + } + } + + /** + *

    This method clears cached global application + * {@link HandlerDefinition}s.

    + */ + public static void clearGlobalHandlerDefinitions(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().remove(HD_MAP); + } + } + + /** + *

    This method provides a means to add an additional global + * {@link Resource} (a {@link Resource} that is available across the + * application). It is recommended that this not be done using this + * method, but instead by registering the global {@link Resource}. + * This can be done by... FIXME: TBD...

    + */ + public static void addGlobalResource(Resource res) { + getGlobalResources(null).add(res); + } + + /** + *

    This method returns a List of global + * {@link Resource}s. The List returned should not be + * changed, it is the actual internal List that is shared + * across the application and it is not thread safe.

    + * + *

    This method will find global resources by... FIXME: TBD...

    + */ + public static List getGlobalResources(FacesContext ctx) { +// FIXME: TBD... + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + List globalResources = null; + if (ctx != null) { + globalResources = (List) ctx.getExternalContext(). + getApplicationMap().get(RES_MAP); + } + if (globalResources == null) { + globalResources = new CopyOnWriteArrayList(); +// FIXME: Find / Initialize resources... + if (ctx != null) { + ctx.getExternalContext().getApplicationMap(). + put(RES_MAP, globalResources); + } + } + + // Return the Resources List + return globalResources; + } + + /** + *

    This method clears the cached global {@link Resource}s.

    + */ + public static void clearGlobalResources(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().remove(RES_MAP); + } + } + + /** + *

    Getter for the debug flag. This version of this method invokes + * the isDebug(FacesContext) method.

    + */ + public static boolean isDebug() { + return isDebug(null); + } + + /** + *

    Returns true if this application is running in debug-mode. Note, + * because this method may be called during initialization before + * it is able to properly deterimine if this flag has been set, it + * will not cache its determination if it does not find an explicit + * setting for this flag. This means you should always set this flag + * for best performance since not setting it will force it to be + * calculated on every request for this value.

    + * + *

    A ServletContext initialization paramter by the + * name of {@link #DEBUG_FLAG} + * ("com.sun.jsftemplating.DEBUG") is the recommended means + * of setting this flag.

    + */ + public static boolean isDebug(FacesContext ctx) { + // Check Application Scope First... + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Object objVal = null; + if (ctx != null) { + objVal = (Boolean) ctx.getExternalContext(). + getApplicationMap().get(DEBUG_FLAG); + if (objVal != null) { + return (Boolean) objVal; + } + } + + // Not found... next check for a system property... + String flag = System.getProperty(DEBUG_FLAG); + if (flag == null) { + if (ctx != null) { + flag = ctx.getExternalContext().getInitParameter(DEBUG_FLAG); + } + } + + // Figure out what we have and save it if explicitly set... + boolean isDebug = false; + if ((ctx != null) && (flag != null)) { + // The environment may not be fully initialized, we don't want it + // to cache the value we may have incorrectly discovered... so only + // cache if found if explicitly found. + // + // Save it in application scope for easier resolution later... + isDebug = Boolean.parseBoolean(flag); + ctx.getExternalContext().getApplicationMap(). + put(DEBUG_FLAG, isDebug); + } + + // Return the flag value... + return isDebug; + } + + /** + *

    Setter for the debug flag. Sets {@link #DEBUG_FLAG} equal to + * flag in application scope.

    + */ + public static void setDebug(FacesContext ctx, boolean flag) { + ctx.getExternalContext().getApplicationMap(). + put(DEBUG_FLAG, flag); + } + + + /** + *

    This key stores the {@link HandlerDefinition}'s for this + * application.

    + */ + private static final String HD_MAP = "__jsft_HandlerDefs"; + + /** + *

    This key stores the {@link LayoutDefinitionManager} instances for + * this application.

    + */ + private static final String LDMS = "__jsft_LayoutDefMgrs"; + + /** + *

    This key stores the {@link LayoutDefinitionManager} class names + * for this application.

    + */ + private static final String LDM_KEYS = "__jsft_LayoutDefMgrKeys"; + + /** + *

    This key stores the {@link LayoutDefinition} instances for this + * application.

    + */ + private static final String LD_MAP = "__jsft_LayoutDefMap"; + + /** + *

    This key stores the {@link ComponentType} instances for this + * application.

    + */ + private static final String CT_MAP = "__jsft_ComponentTypeMap"; + + /** + *

    This key stores the global {@link Resource} instances for this + * application.

    + */ + private static final String RES_MAP = "__jsft_ResourceMap"; + + /** + *

    This map contains sub-class specific attributes that may be needed + * by specific implementations of + * LayoutDefinitionManagers. For example, setting an + * EntityResolver on a + * LayoutDefinitionManager that creates + * LayoutDefinitions from XML files.

    + */ + private Map _attributes = new HashMap(); + + /** + *

    This Map holds global {@link ComponentType}s so they + * can be defined once and shared across the application.

    + */ + private static Map _globalComponentTypes = null; + + private static final HandlerDefinition NOOP_HD = + new HandlerDefinition("_NOOP_"); + + /** + *

    This is the default input and output type.

    + */ + public static final String DEFAULT_TYPE = "Object"; + + /** + *

    This constant defines the LayoutDefinitionManager + * implementation key for initParams. + * ("LayoutDefinitionManagerImpl")

    + */ + public static final String LAYOUT_DEFINITION_MANAGER_KEY = + "LayoutDefinitionManagerImpl"; + + /** + *

    This is the name of the initParameter or JVM variable used to set + * the DEBUG flag.

    + */ + public static final String DEBUG_FLAG = "com.sun.jsftemplating.DEBUG"; + + /** + *

    This is the prefix of a request-scoped variable that caches + * {@link LayoutDefinition}s.

    + */ + public static final String CACHE_PREFIX = "_LDCache"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutViewHandler.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutViewHandler.java new file mode 100644 index 0000000..be6fd1a --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutViewHandler.java @@ -0,0 +1,939 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Stack; +import java.util.Set; +import java.util.HashSet; + +import javax.faces.FactoryFinder; +import javax.faces.application.StateManager; +import javax.faces.application.ViewHandler; +import javax.faces.application.StateManager.SerializedView; +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import javax.faces.render.RenderKit; +import javax.faces.render.RenderKitFactory; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.sun.jsftemplating.el.PageSessionResolver; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutComposition; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.LayoutFacet; +import com.sun.jsftemplating.layout.descriptors.LayoutInsert; +import com.sun.jsftemplating.layout.descriptors.Resource; +import com.sun.jsftemplating.util.LayoutElementUtil; +import com.sun.jsftemplating.util.LogUtil; +import com.sun.jsftemplating.util.SimplePatternMatcher; +import com.sun.jsftemplating.util.TypeConversion; +import com.sun.jsftemplating.util.TypeConverter; +import com.sun.jsftemplating.util.UIComponentTypeConversion; +import com.sun.jsftemplating.util.fileStreamer.Context; +import com.sun.jsftemplating.util.fileStreamer.FacesStreamerContext; +import com.sun.jsftemplating.util.fileStreamer.FileStreamer; + + +// FIXME: Things to consider: +// FIXME: - What is necessary to support Portlets... +// FIXME: - Should I attempt to clean up old unused UIComponents? +// FIXME: - f:view supported setting locale, I should too... + +/** + *

    This class provides a custom ViewHandler that is able to + * create and populate a UIViewRoot from a + * {@link LayoutDefinition}. This is often defined by an XML document, + * the default implementation's DTD is defined in + * layout.dtd.

    + * + *

    Besides the default ViewHandler behavior, this class is + * responsible for using the given viewId as the + * {@link LayoutDefinition} key and setting it on the UIViewRoot that is + * created. It will obtain the {@link LayoutDefinition}, initialize the + * declared {@link Resource}s, and instantiate UIComponent + * tree using the {@link LayoutDefinition}'s declared + * {@link LayoutComponent} structure. During rendering, it delegates to + * the {@link LayoutDefinition}.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutViewHandler extends ViewHandler { + + /** + *

    Constructor.

    + * + * @param oldViewHandler The old ViewHandler. + */ + public LayoutViewHandler(ViewHandler oldViewHandler) { + _oldViewHandler = oldViewHandler; + +// FIXME: Fire an initializtion event, work out how to listen for this event + + // This is added here to ensure that if the ViewHandler is reloaded in + // a running application, that handlers, ct's, and resources will get + // re-read. Ryan added a feature which may introduce this code path. + LayoutDefinitionManager.clearGlobalComponentTypes(null); + LayoutDefinitionManager.clearGlobalHandlerDefinitions(null); + LayoutDefinitionManager.clearGlobalResources(null); + } + + /** + *

    Initialize the view for the request processing lifecycle. It is + * called at the beginning of the Restore View phase.

    + public void initView(FacesContext context) throws FacesException { + // Not used yet... I left this here as a reminder that it is here + } + */ + + /** + *

    This method is invoked when restoreView does not yield a + * UIViewRoot (initial requests and new pages).

    + * + *

    This implementation should work with both + * {@link LayoutDefinition}-based pages as well as traditional + * JSP pages (or other frameworks).

    + */ + public UIViewRoot createView(FacesContext context, String viewId) { +//_time = new java.util.Date(); + // Check to see if this is a resource request + String path = getResourcePath(viewId); + if (path != null) { + // Serve Resource + return serveResource(context, path); + } + + // Check to see if jsftemplating should create the view + if(!this.isMappedView(viewId) || (viewId == null)) { + UIViewRoot viewRoot = _oldViewHandler.createView(context, viewId); + return viewRoot; + } + + Locale locale = null; + String renderKitId = null; + + // use the locale from the previous view if is was one which will be + // the case if this is called from NavigationHandler. There wouldn't be + // one for the initial case. + if (context.getViewRoot() != null) { + UIViewRoot oldViewRoot = context.getViewRoot(); + LayoutDefinition oldLD = ViewRootUtil.getLayoutDefinition(oldViewRoot); + if ((oldLD != null) && oldViewRoot.getViewId().equals(viewId)) { + // If you navigate to the page you are already on, JSF will + // re-create the UIViewRoot of the current page. The initPage + // event needs to be reset so that it will re-execute itself. + oldLD.setInitPageExecuted(context, Boolean.FALSE); + } + locale = context.getViewRoot().getLocale(); + renderKitId = context.getViewRoot().getRenderKitId(); + } + + // Create the ViewRoot + UIViewRoot viewRoot = _oldViewHandler.createView(context, viewId); + viewRoot.setViewId(viewId); + ViewRootUtil.setLayoutDefinitionKey(viewRoot, viewId); + + // if there was no locale from the previous view, calculate the locale + // for this view. + if (locale == null) { + locale = calculateLocale(context); + } + viewRoot.setLocale(locale); + + // set the renderkit + if (renderKitId == null) { + renderKitId = calculateRenderKitId(context); + } + viewRoot.setRenderKitId(renderKitId); + + // Save the current viewRoot, temporarily set the new UIViewRoot so + // beforeCreate, afterCreate will function correctly + UIViewRoot currentViewRoot = context.getViewRoot(); + + // Set the View Root to the new viewRoot + // NOTE: This must happen after return _oldViewHandler.createView(...) + // NOTE2: However, we really want the UIViewRoot available during + // initPage events which are fired during + // getLayoutDefinition()... so we need to set this, then unset + // it if we go through _oldViewHandler.createView(...) + context.setViewRoot(viewRoot); + + // Initialize Resources / Create Tree + LayoutDefinition def = null; + try { + def = ViewRootUtil.getLayoutDefinition(viewRoot); + } catch (LayoutDefinitionException ex) { + if (LogUtil.configEnabled()) { + LogUtil.config("JSFT0005", (Object) viewId); + if (LogUtil.finestEnabled()) { + LogUtil.finest( + "File (" + viewId + ") not found!", ex); + } + } + + // Restore original ViewRoot, we set it prematurely + if (currentViewRoot != null) { +// FIXME: Talk to Ryan about restoring the ViewRoot to null!! + context.setViewRoot(currentViewRoot); + } + +// FIXME: Provide better feedback when no .jsf & no .jsp +// FIXME: Difficult to tell at this stage if no .jsp is present + + // Not found, delegate to old ViewHandler + return _oldViewHandler.createView(context, viewId); + } catch (RuntimeException ex) { + // Restore original ViewRoot, we set it prematurely + if (currentViewRoot != null) { +// FIXME: Talk to Ryan about restoring the ViewRoot to null!! + context.setViewRoot(currentViewRoot); + } + + // Allow error to be thrown (this isn't the normal code path) + throw ex; + } + + // We need to do this again b/c an initPage handler may have changed + // the viewRoot + viewRoot = context.getViewRoot(); + + // Check to make sure we found a LD and that the response isn't + // already finished (initPage could complete the response... + // i.e. during a redirect). + if ((def != null) && !context.getResponseComplete()) { + // Ensure that our Resources are available + Iterator it = def.getResources().iterator(); + Resource resource = null; + while (it.hasNext()) { + resource = it.next(); + // Just calling getResource() puts it in the Request scope + resource.getFactory().getResource(context, resource); + } + + // Get the Tree and pre-walk it + if (LayoutDefinitionManager.isDebug(context)) { + // Make sure to reset all the client ids we're about to check + getClientIdMap(context).clear(); + } + buildUIComponentTree(context, viewRoot, def); + } + + // Restore the current UIViewRoot + if (currentViewRoot != null) { + context.setViewRoot(currentViewRoot); + } + + // Return the populated UIViewRoot + return viewRoot; + } + + /** + *

    Tests if the provided viewId matches one of the + * configured view-mappings. If no view-mappings are defined, all + * viewIds will match.

    + * + * @param viewId The viewId to be tested. + * + * @return true If the viewId matched or no view-mappings are defined, + * false otherwise. + * @since 1.2 + */ + private boolean isMappedView(String viewId) { + if (this._viewMappings == null) { + String initParam = (String) FacesContext.getCurrentInstance(). + getExternalContext().getInitParameterMap().get(VIEW_MAPPINGS); + this._viewMappings = SimplePatternMatcher. + parseMultiPatternString(initParam, ";"); + } + if (this._viewMappings.isEmpty()) { + return true; + } + for (SimplePatternMatcher mapping : this._viewMappings) { + if (mapping.matches(viewId)) { + return true; + } + } + return false; + } + + /** + *

    If this is a resource request, this method will handle the + * request.

    + */ + public static UIViewRoot serveResource(FacesContext context, String path) { + // Mark the response complete so no more processing occurs + context.responseComplete(); + + // Create dummy UIViewRoot + UIViewRoot root = new UIViewRoot(); + root.setRenderKitId("dummy"); + + // Setup the FacesStreamerContext + Context fsContext = new FacesStreamerContext(context); + fsContext.setAttribute(Context.FILE_PATH, path); + + // Get the HttpServletResponse + Object obj = context.getExternalContext().getResponse(); + HttpServletResponse resp = null; + if (obj instanceof HttpServletResponse) { + resp = (HttpServletResponse) obj; + + // We have an HttpServlet response, do some extra stuff... + // Check the last modified time to see if we need to serve the resource + long mod = fsContext.getContentSource().getLastModified(fsContext); + if (mod != -1) { + long ifModifiedSince = ((HttpServletRequest) + context.getExternalContext().getRequest()). + getDateHeader("If-Modified-Since"); + // Round down to the nearest second for a proper compare + if (ifModifiedSince < (mod / 1000 * 1000)) { + // A ifModifiedSince of -1 will always be less + resp.setDateHeader("Last-Modified", mod); + } else { + // Set not modified header and complete response + resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + return root; + } + } + } + + // Stream the content + try { + FileStreamer.getFileStreamer(context).streamContent(fsContext); + } catch (FileNotFoundException ex) { + if (LogUtil.infoEnabled()) { + LogUtil.info("JSFT0004", (Object) path); + } + if (resp != null) { + try { + ((HttpServletResponse) resp).sendError( + HttpServletResponse.SC_NOT_FOUND); + } catch (IOException ioEx) { + // Ignore + } + } + } catch (IOException ex) { + if (LogUtil.infoEnabled()) { + LogUtil.info("JSFT0004", (Object) path); + if (LogUtil.fineEnabled()) { + LogUtil.fine( + "Resource (" + path + ") not available!", ex); + } + } +// FIXME: send 404? + } + + // Return dummy UIViewRoot to avoid NPE + return root; + } + + /** + *

    Returns the current encoding type.

    + * + * @param ctx The FacesContext. + */ + public static String getEncoding(FacesContext ctx) { + // Sanity check + if (ctx == null) { + return null; + } + + String encType = null; + UIViewRoot root = ctx.getViewRoot(); + Map map = PageSessionResolver.getPageSession(ctx, root); + if (map != null) { + //check for page session + encType = (String) map.get(ENCODING_TYPE); + } + if ((encType == null) || encType.equals("")) { + //check for application level + encType = ctx.getExternalContext().getInitParameter(ENCODING_TYPE); + } + if ((encType == null) || encType.equals("")) { + ExternalContext extCtx = ctx.getExternalContext(); + try { + ServletRequest request = (ServletRequest) extCtx.getRequest(); + encType = request.getCharacterEncoding(); + } catch (Exception ex) { + // FIXME: Portlet? + } + if ((encType == null) || encType.equals("")) { + //default encoding type + encType="UTF-8"; + } + } + return encType; + } + + /** + *

    This method checks the given viewId and returns a the path to the + * requested resource if it refers to a resource. Resources are + * things like JavaScript files, images, etc. Basically anything that + * is not a JSF page that you'd like to serve up via the FacesServlet. + * Serving resources this way allows you to bundle the resources in a + * jar file, this is useful if you want to package up part of an app + * (or a JSF component) in a single file.

    + * + *

    A request for a resource must be prefixed by the resource prefix, + * see @{link #getResourcePrefixes}. This prefix must also be mapped to + * the FacesServlet in order for this class to handle the + * request.

    + */ + public String getResourcePath(String viewId) { + ExternalContext extCtx = FacesContext.getCurrentInstance().getExternalContext(); +// FIXME: Portlet! + String servletPath = extCtx.getRequestServletPath(); + Iterator it = getResourcePrefixes().iterator(); + while (it.hasNext()) { + if (servletPath.equals(it.next())) { + return extCtx.getRequestPathInfo(); + } + } + return null; + } + + /** + *

    This method returns the prefix that a URL must contain in order to + * retrieve a "resource" through this ViewHandler.

    + * + *

    The prefix itself does not manifest itself in the file system / + * classpath.

    + * + *

    If the prefix is not set, then an init parameter (see + * {@link #RESOURCE_PREFIX}) will be checked. If that is still not + * specified, then the {@link #DEFAULT_RESOURCE_PREFIX} will be + * used.

    + */ + public Set getResourcePrefixes() { + if (_resourcePrefix == null) { + HashSet set = new HashSet(); + // Check to see if it's specified by a context param + // Get context parameter map (initParams in JSF are context params) + String initParam = (String) FacesContext.getCurrentInstance(). + getExternalContext().getInitParameterMap().get(RESOURCE_PREFIX); + if (initParam != null) { + for(String token: initParam.split(",")) { + set.add(token.trim()); + } + } + // Add default... + set.add(DEFAULT_RESOURCE_PREFIX); + _resourcePrefix = set; + } + return _resourcePrefix; + } + + /** + *

    This method allows a user to set the resource prefix which will be + * checked to obtain a resource via this Viewhandler. + * Currently, only 1 prefix is supported. The prefix itself does not + * manifest itself in the file system / classpath.

    + */ + public void setResourcePrefixes(Set prefix) { + _resourcePrefix = prefix; + } + + /** + *

    This method iterates over the child {@link LayoutElement}s of the + * given elt to create UIComponents for each + * {@link LayoutComponent}.

    + * + * @param context The FacesContext. + * @param parent The parent UIComponent of the + * UIComponent to be found or created. + * @param elt The LayoutElement driving everything. + */ + public static void buildUIComponentTree(FacesContext context, UIComponent parent, LayoutElement elt) { +// FIXME: Consider processing *ALL* LayoutElements so that and others +// FIXME: have meaning when inside other components. + Iterator it = elt.getChildLayoutElements().iterator(); + LayoutElement childElt; + UIComponent child = null; + while (it.hasNext()) { + childElt = it.next(); + if (childElt instanceof LayoutFacet) { + if (!((LayoutFacet) childElt).isRendered()) { + // The contents of this should be a single UIComponent + buildUIComponentTree(context, parent, childElt); + } + // NOTE: LayoutFacets that aren't JSF facets aren't + // NOTE: meaningful in this context + } else if (childElt instanceof LayoutComposition) { + LayoutComposition compo = ((LayoutComposition) childElt); + String template = compo.getTemplate(); + if (template != null) { + // Add LayoutComposition to the stack + LayoutComposition.push(context, childElt); + + try { + // Add the template here. + buildUIComponentTree(context, parent, LayoutDefinitionManager.getLayoutDefinition( + context, template)); + } catch (LayoutDefinitionException ex) { + if (((LayoutComposition) childElt).isRequired()) { + throw ex; + } + } + + // Remove the LayoutComposition from the stack + LayoutComposition.pop(context); + } else { + // In this case we don't have a template, so instead we + // render the body + buildUIComponentTree(context, parent, childElt); + } + } else if (childElt instanceof LayoutInsert) { + Stack stack = + LayoutComposition.getCompositionStack(context); + if (stack.empty()) { + // No template-client found... + // Is this supposed to do nothing? Or throw an exception? + throw new IllegalArgumentException( + "'ui:insert' encountered, however, no " + + "'ui:composition' was used!"); + } + + // Get associated UIComposition + String insertName = ((LayoutInsert) childElt).getName(); + if (insertName == null) { + // include everything + buildUIComponentTree(context, parent, stack.get(0)); + } else { + // First resolve any EL in the insertName + insertName = "" + ((LayoutInsert) childElt).resolveValue( + context, parent, insertName); + + // Search for specific LayoutDefine + LayoutElement def = LayoutInsert.findLayoutDefine( + context, parent, stack, insertName); + if (def == null) { + // Not found include the body-content of the insert + buildUIComponentTree(context, parent, childElt); + } else { + // Found, include the ui:define content + buildUIComponentTree(context, parent, def); + } + } + } else if (childElt instanceof LayoutComponent) { + // Calling getChild will add the child UIComponent to tree + child = ((LayoutComponent) childElt). + getChild(context, parent); + + if (LayoutDefinitionManager.isDebug(context)) { + // To help developer avoid duplicate ids, we'll check the + // ids here. + Map idMap = getClientIdMap(context); + String id = child.getClientId(context); + if (idMap.containsKey(id)) { + if (!((LayoutComponent) childElt).containsOption(LayoutComponent.SKIP_ID_CHECK) && LogUtil.warningEnabled()) { + LogUtil.warning("JSFT0011", (Object) id); + } + + // Clear the map as a way to prevent this message from + // being shown tons of times as may occur in some + // valid use cases. Remember this is just a debug-time + // only helpful message anyway... + idMap.clear(); + } + idMap.put(id, id); + } + + // Check for events + // NOTE: For now I am only supporting "action" and + // NOTE: "actionListener" event types. In the future it + // NOTE: may be desirable to support beforeEncode / + // NOTE: afterEncode as well. At this time, those events + // NOTE: are supported by the "Event" UIComponent. That + // NOTE: component can wrap non-layout-based components to + // NOTE: achieve this functionality (supporting that + // NOTE: functionality here will simply do the same thing + // NOTE: automatically). + + // Recurse + buildUIComponentTree(context, child, childElt); + } else { + buildUIComponentTree(context, parent, childElt); + } + } + } + + /** + *

    This method provides access to a Map of clientIds + * that have been used in this page.

    + */ + private static Map getClientIdMap(FacesContext context) { + Map reqMap = + context.getExternalContext().getRequestMap(); + Map idMap = (Map) + reqMap.get("__debugIdMap"); + if (idMap == null) { + idMap = new HashMap(); + reqMap.put("__debugIdMap", idMap); + } + return idMap; + } + + /** + *

    This implementation relies on the default behavior to reconstruct + * the UIViewRoot.

    + * + *

    ...

    + */ + public UIViewRoot restoreView(FacesContext context, String viewId) { +//_time = new java.util.Date(); + Map map = context.getExternalContext().getRequestMap(); + if (map.get(RESTORE_VIEW_ID) == null) { + map.put(RESTORE_VIEW_ID, viewId); + } else { + // This request has already been processed, it must be a forward() + return createView(context, viewId); + } + + // Perform default behavior... + UIViewRoot root = _oldViewHandler.restoreView(context, viewId); + + // We can check for JSFT UIViewRoots by calling + // getLayoutDefinitionKey(root) as this will return null if not JSFT + if (root != null) { + String key = ViewRootUtil.getLayoutDefinitionKey(root); + if (key != null) { + // Set the View Root to the new viewRoot (needed for initPage) + // NOTE: See createView note about saving / restoring the + // NOTE: original UIViewRoot and issue with setting it to + // NOTE: (null). restoreView is less important b/c it is not + // NOTE: normally called by a developer or framework as + // NOTE: navigation rules will call createView. For this + // NOTE: reason, I am not resetting the UIViewRoot for now. + context.setViewRoot(root); + + // Call getLayoutDefinition() to ensure initPage events are + // fired, only do this for JSFT ViewRoots. Its good to call + // this after restoreView as we need the UIViewRoot available + // during initPage events. Formerly this was done during the + // ApplyRequestValuesPhase, however, I no longer have a custom + // UIViewRoot to use for this purpose, so I will do it here, + // which should be just as good. + LayoutDefinition def = ViewRootUtil.getLayoutDefinition(key); + + // While we're at it, we should call the LD decode() event so + // we can provide a page-level decode() functionality. This + // won't effect components in the page, or JSFT-based + // components. + def.decode(context, root); + } + } + + // Return the UIViewRoot + return root; + } + + /** + * + */ + public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException { + // Make sure we have a def + LayoutDefinition def = ViewRootUtil.getLayoutDefinition(viewToRender); + if (def == null) { + // PartialRequest or No def, fall back to default behavior + _oldViewHandler.renderView(context, viewToRender); + } else { + // Start document + if (!context.getPartialViewContext().isPartialRequest() || context.getPartialViewContext().isRenderAll()) { + ResponseWriter writer = setupResponseWriter(context); + writer.startDocument(); + + // Render content + def.encode(context, viewToRender); + + // End document + writer.endDocument(); + } else { + // NOTE: This "if" branch has been added to avoid the + // NOTE: start/endDocument calls being called 2x on PartialView + // NOTE: requests. JSF Issue #1307 has been filed to resolve + // NOTE: this correctly (assuming checking here is not + // NOTE: correct... which I do not feel that it is). + // + // Render content + def.encode(context, viewToRender); + } + } +//System.out.println("PROCESSING TIME: " + (new java.util.Date().getTime() - _time.getTime())); + } + + private static void renderComponent(FacesContext context, UIComponent comp) throws IOException { + if (!comp.isRendered()) { + return; + } + + comp.encodeBegin(context); + if (comp.getRendersChildren()) { + comp.encodeChildren(context); + } else { + UIComponent child = null; + Iterator it = comp.getChildren().iterator(); + while (it.hasNext()) { + child = it.next(); + renderComponent(context, child); + } + } + comp.encodeEnd(context); + } + + /** + * + */ + private ResponseWriter setupResponseWriter(FacesContext context) throws IOException { + ResponseWriter writer = context.getResponseWriter(); + if (writer != null) { + // It is already setup + return writer; + } + + ExternalContext extCtx = context.getExternalContext(); +// FIXME: Portlet? + ServletResponse response = (ServletResponse) extCtx.getResponse(); + + RenderKitFactory renderFactory = (RenderKitFactory) + FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); + RenderKit renderKit = + renderFactory.getRenderKit(context, + context.getViewRoot().getRenderKitId()); + + // See if the user (page author) specified a ContentType... + String contentTypeList = null; +// FIXME: Provide a way for the user to specify this... +// FIXME: Test multiple browsers against this code!! + String userContentType = "text/html"; + if((userContentType != null) && (userContentType.length() > 0)) { + // User picked this, use it... + response.setContentType(userContentType); + } + else { + // No explicit Content-type, find best match... + contentTypeList = (String) extCtx.getRequestHeaderMap().get("Accept"); + if (contentTypeList == null) { + contentTypeList = "text/html;q=1.0"; + } + } + String encType = getEncoding(context); + // Object encValue = extCtx.getSessionMap().get( + // ViewHandler.CHARACTER_ENCODING_KEY); + + extCtx.getSessionMap().put(ViewHandler.CHARACTER_ENCODING_KEY, + encType); +// FIXME: use the external context to set the character encoding, it is supported + response.setCharacterEncoding(encType); + +// FIXME: Portlet? + writer = + renderKit.createResponseWriter( + new OutputStreamWriter(response.getOutputStream(), encType), + contentTypeList, encType); + context.setResponseWriter(writer); +// Not setting the contentType here results in XHTML which formats differently +// than text/html in Mozilla.. even though the documentation claims this +// works, it doesn't (try viewing the Tree) +// response.setContentType("text/html"); + + // As far as I can tell JSF doesn't ever set the Content-type that it + // works so hard to calculate... This is the code we should be + // calling, however we can't do this yet + response.setContentType(writer.getContentType()); + + return writer; + } + + /** + *

    Take any appropriate action to either immediately write out the + * current state information (by calling + * StateManager.writeState, or noting where state + * information should later be written.

    + * + * @param context FacesContext for the current request + * + * @exception IOException if an input/output error occurs + */ + public void writeState(FacesContext context) throws IOException { + // Check to see if we should delegate back to the legacy ViewHandler + UIViewRoot root = context.getViewRoot(); +// FIXME: For now I am treating "@all" Ajax requests as normal requests... +// FIXME: Otherwise the view state is not written. + if ((root == null) || (context.getPartialViewContext().isPartialRequest() && !context.getPartialViewContext().isRenderAll()) + || (ViewRootUtil.getLayoutDefinition(root) == null)) { + // Use old behavior... + _oldViewHandler.writeState(context); + } else { + // b/c we pre-processed the ViewTree, we can just add it... + StateManager stateManager = + context.getApplication().getStateManager(); + SerializedView view = stateManager.saveSerializedView(context); + + // New versions of JSF 1.2 changed the contract so that state is + // always written (client and server state saving) + stateManager.writeState(context, view); + } + } + + /** + *

    Return a URL suitable for rendering (after optional encoding + * performed by the encodeResourceURL() method of + * ExternalContext that selects the specified web + * application resource. If the specified path starts with a slash, + * it must be treated as context relative; otherwise, it must be + * treated as relative to the action URL of the current view.

    + * + * @param context FacesContext for the current request + * @param path Resource path to convert to a URL + * + * @exception IllegalArgumentException If viewId is not + * valid for this ViewHandler. + */ + public String getResourceURL(FacesContext context, String path) { + return _oldViewHandler.getResourceURL(context, path); + } + + /** + *

    Return a URL suitable for rendering (after optional encoding + * performed by the encodeActionURL() method of + * ExternalContext that selects the specified view + * identifier.

    + * + * @param context FacesContext for this request + * @param viewId View identifier of the desired view + * + * @exception IllegalArgumentException If viewId is not + * valid for this ViewHandler. + */ + public String getActionURL(FacesContext context, String viewId) { + return _oldViewHandler.getActionURL(context, viewId); + } + + /** + *

    Returns an appropriate Locale to use for this and + * subsequent requests for the current client.

    + * + * @param context FacesContext for the current request + * + * @exception NullPointerException if context is + * null + */ + public Locale calculateLocale(FacesContext context) { + return _oldViewHandler.calculateLocale(context); + } + + /** + *

    Return an appropriate renderKitId for this + * and subsequent requests from the current client.

    + * + *

    The default return value is + * javax.faces.render.RenderKitFactory.HTML_BASIC_RENDER_KIT. + *

    + * + * @param context FacesContext for the current request. + */ + public String calculateRenderKitId(FacesContext context) { + return _oldViewHandler.calculateRenderKitId(context); + } + + /** + *

    This is the key that may be used to identify the clientId of the + * UIComponent that is to be updated via an Ajax request.

    + */ + public static final String AJAX_REQ_KEY = "ajaxReq"; + + public static final String RESTORE_VIEW_ID = "_resViewID"; + + /** + *

    This is the default prefix that must be included on all requests + * for resources.

    + */ + public static final String DEFAULT_RESOURCE_PREFIX = "/resource"; + + /** + *

    The name of the context-param to set the resource + * prefix.

    + */ + public static final String RESOURCE_PREFIX = + "com.sun.jsftemplating.RESOURCE_PREFIX"; + + private Set _resourcePrefix = null; +//private transient java.util.Date _time = null; + + private ViewHandler _oldViewHandler = null; + static final String AJAX_REQ_TARGET_KEY = "_ajaxReqTarget"; + + /** + *

    The name of the context-param to set the view mappings

    + */ + // TODO: should these keys be added to a new Class f.e. com.sun.jsftemplating.Keys? + private static final String VIEW_MAPPINGS = + "com.sun.jsftemplating.VIEW_MAPPINGS"; + + /** + * + */ + private static final TypeConversion UICOMPONENT_TYPE_CONVERSION = + new UIComponentTypeConversion(); + + /* + *

    This is intended to initialize additional type conversions + * for the {@link TypeConverter}. These additional type conversions + * are typically specific to JSF or JSFTemplating. If you are + * reading this and want additional custom type conversions, bug + * Ken Paulsen to add an init event which will allow you to easily + * initialize your own type conversions.

    + */ + static { + // Add type conversions by class + TypeConverter.registerTypeConversion(null, UIComponent.class, UICOMPONENT_TYPE_CONVERSION); + // Add type conversions by class name + TypeConverter.registerTypeConversion(null, UIComponent.class.getName(), UICOMPONENT_TYPE_CONVERSION); + } + + + private Collection _viewMappings = null; + + /** + *

    This key can be used to override the encoding type used in your + * application.

    + */ + public static final String ENCODING_TYPE="com.sun.jsftemplating.ENCODING"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/ProcessingCompleteException.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/ProcessingCompleteException.java new file mode 100644 index 0000000..226c949 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/ProcessingCompleteException.java @@ -0,0 +1,65 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout; + +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; + +/** + *

    This exception is thrown to signal the parser to stop processing.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ProcessingCompleteException extends RuntimeException { + private static final long serialVersionUID = 1L; + + /** + *

    The constructor.

    + */ + public ProcessingCompleteException(LayoutDefinition ld) { + super("Processing completed early."); + _layoutDef = ld; + } + + /** + *

    This method is here to prevent the superclass method from eating + * up time. This implementation does not require a stack trace. + * This method simply returns this.

    + */ + @Override + public Throwable fillInStackTrace() { + return this; + } + + /** + *

    Accessor for the {@link LayoutDefinition} to be used.

    + */ + public LayoutDefinition getLayoutDefinition() { + return _layoutDef; + } + + /** + *

    This hold the {@link LayoutDefinition} which should be used as + * the result of processing the file.

    + */ + private LayoutDefinition _layoutDef = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/SyntaxException.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/SyntaxException.java new file mode 100644 index 0000000..5fcb911 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/SyntaxException.java @@ -0,0 +1,62 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout; + +import com.sun.jsftemplating.TemplatingException; + + +/** + *

    This exception is thrown when a syntax error has occurred. For i/o + * related exceptions, see {@link LayoutDefinitionException}.

    + */ +public class SyntaxException extends TemplatingException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public SyntaxException(String msg, Throwable ex) { + super(msg, ex); + } + + /** + * + */ + public SyntaxException() { + super(); + } + + /** + * + */ + public SyntaxException(Throwable ex) { + super(ex); + } + + /** + * + */ + public SyntaxException(String msg) { + super(msg); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/ViewRootUtil.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/ViewRootUtil.java new file mode 100644 index 0000000..ff8c9d4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/ViewRootUtil.java @@ -0,0 +1,289 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout; + +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; + +import java.util.Map; + +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + + +/** + *

    This class provides utility methods used by JSFT for working with + * UIViewRoot instances. JSFTemplating no longer provides + * its own UIViewRoot, in an effort to make integration + * with other frameworks more simple. The methods in this class perform + * operations such as setting the {@link LayoutDefinition} key on the + * UIViewRoot as an attribute. It also allows you go obtain + * the {@link LayoutDefinition} used by a specific instance of the + * UIViewRoot, or the current instance set in the + * FacesContext.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ViewRootUtil { + + /** + *

    Constructor. All methods are static, no need to instantiate this + * class.

    + */ + private ViewRootUtil() { + } + + /** +// FIXME: This method was originally from the LayoutViewRoot class (which +// FIXME: extended UIViewRoot). This method allowed "decode" events to work +// FIXME: on pages. I still need to replace this functionality w/o extending +// FIXME: the UIViewRoot (if possible). + + *

    This method enables the decode event to work for pages.

    + * + *

    This method checks for Ajax requests and treats them differently + * than normal requests. It only decodes the targeted UIComponent + * (and its children), then invokes processApplication(), and finally + * renders a partial response (rendering change is actually handled + * by LayoutViewHandler).

    + * + *

    When decoding template-based components, this is handled by the + * TemplateRenderer. However, when dealing with pages, this is done + * here (TemplateRenderer is not involved to fire handlers).

    + * + *

    This method continues to delegate to the superclass after invoking + * any registered handlers.

    + public void processDecodes(FacesContext context) { + // PartialTraversalViewRootHelper may call us in an attempt to call + // super.processDecodes(), detect this... + if (!(new RuntimeException().getStackTrace()[1].getClassName().equals(HELPER_NAME)) && + !helper.processDecodes(context)) { + // Request already handled... + return; + } + +// BEGIN EXPERIMENTAL CODE... + ExternalContext extCtx = context.getExternalContext(); + String targetId = extCtx.getRequestParameterMap().get(LayoutViewHandler.AJAX_REQ_KEY); + if ((targetId != null) && !targetId.equals("")) { + // Detected Ajax Request + // This request will only process a sub-tree of the UIComponent + // tree and return the cooresponding partial HTML + + // First find the Ajax target + UIComponent target = findComponent(":"+targetId); + if (target == null) { + // FIXME: Log a warning message! + // FIXME: Rework this so that the following 6 lines are duplicated + LayoutDefinition def = getLayoutDefinition(context); + if (def != null) { + def.decode(context, this); + } + super.processDecodes(context); + return; + } + extCtx.getRequestMap().put(LayoutViewHandler.AJAX_REQ_TARGET_KEY, target); + + // Process sub-tree (similar to immedate, no validation/update) + target.processDecodes(context); + processApplication(context); + + // Mark the context that the next phase should be RenderResponse + context.renderResponse(); + } else { + // END EXPERIMENTAL CODE... + + LayoutDefinition def = getLayoutDefinition(context); + if (def != null) { + def.decode(context, this); + } + super.processDecodes(context); + } + } + */ + + /** + *

    This method provides the ability to obtain a "child" + * UIComponent from this UIViewRoot.

    + * + * @param context The FacesContext. + * @param id The id of UIComponent child. + * + * @return The requested UIComponent or null if not found. + public UIComponent getChild(FacesContext context, String id) { + if ((id == null) || (id.trim().equals(""))) { + // No id, no LayoutComponent, nothing we can do. + return null; + } + + // We have an id, use it to search for an already-created child + UIComponent childComponent = ComponentUtil.getInstance(context).findChild(this, id, id); + if (childComponent != null) { + return childComponent; + } + + // If we're still here, then we need to create it... hopefully we have + // a LayoutComponent to tell us how to do this! + LayoutDefinition ld = getLayoutDefinition(context); + if (ld == null) { + // No LayoutDefinition to tell us how to create it... return null + return null; + } + + // Attempt to find a LayoutComponent matching the id + LayoutElement elt = + LayoutDefinition.getChildLayoutElementById(context, id, ld, this); + + // Create the child from the LayoutComponent + return getChild(context, (LayoutComponent) elt); + } + */ + + /** + *

    This method provides the ability to obtain a "child" + * UIComponent from this UIViewRoot. If + * the child does not already exist, it will be created using the + * given {@link LayoutComponent} descriptor.

    + * + * @param context The FacesContext. + * @param descriptor The {@link LayoutComponent} for the + * UIComponent child. + * + * @return The requested UIComponent. + * + * @throws IllegalArgumentException if descriptor is null. + public UIComponent getChild(FacesContext context, LayoutComponent descriptor) { + UIComponent childComponent = null; + + // Sanity check + if (descriptor == null) { + throw new IllegalArgumentException("The LayoutComponent is null!"); + } + + // First pull off the id from the descriptor + String id = descriptor.getId(context, this); + if ((id != null) && !(id.trim().equals(""))) { + // We have an id, use it to search for an already-created child + childComponent = ComponentUtil.getInstance(context).findChild(this, id, id); + if (childComponent != null) { + return childComponent; + } + } + + // No id, or the component hasn't been created. In either case, we + // create a new component (moral: always have an id) + + // Invoke "beforeCreate" handlers + descriptor.beforeCreate(context, this); + + // Create UIComponent + childComponent = + ComponentUtil.getInstance(context).createChildComponent(context, descriptor, this); + + // Invoke "afterCreate" handlers + descriptor.afterCreate(context, childComponent); + + // Return the newly created UIComponent + return childComponent; + } + */ + + /** + *

    Returns the {@link LayoutDefinition} used by the given + * UIViewRoot. This method retrieves the + * {@link LayoutDefinition} key from the given UIViewRoot + * (or gets the current UIViewRoot from the + * FacesContext if the value passed in is + * null. It then invokes the overloaded method + * ({@link #getLayoutDefinition(String)}) with this key.

    + * + * @param root The UIViewRoot to use. + * + * @return The {@link LayoutDefinition} for this UIViewRoot. + */ + public static LayoutDefinition getLayoutDefinition(UIViewRoot root) throws LayoutDefinitionException { + if (root == null) { + // Default to the current UIViewRoot + root = FacesContext.getCurrentInstance().getViewRoot(); + } + return (root == null) ? null : getLayoutDefinition((String) + getLayoutDefinitionKey(root)); + } + + /** + *

    This method returns the {@link LayoutDefinition} for the given + * key. If the {@link LayoutDefinition} has already be + * retrieved during this request, it will be returned. Otherwise, it + * will ask the {@link LayoutDefinitionManager}.

    + */ + public static LayoutDefinition getLayoutDefinition(String key) throws LayoutDefinitionException { + // Make sure the key is not null + if (key == null) { + return null; + } + + // Get the FacesContext + FacesContext context = FacesContext.getCurrentInstance(); + + // Make sure we don't already have it... + Map requestMap = + context.getExternalContext().getRequestMap(); + LayoutDefinition ld = (LayoutDefinition) + requestMap.get(LAYOUT_DEFINITION_KEY + key); + if (ld != null) { + return ld; + } + + // Find it... + ld = LayoutDefinitionManager.getLayoutDefinition(context, key); + + // Save the LayoutDefinition for future calls to this method + requestMap.put(LAYOUT_DEFINITION_KEY + key, ld); + + // Return the LayoutDefinition (if found) + return ld; + } + + /** + *

    This method gets the {@link LayoutDefinition} key from the given + * UIViewRoot.

    + */ + public static String getLayoutDefinitionKey(UIViewRoot root) { + return (String) root.getAttributes().get(LAYOUT_DEFINITION_KEY); + } + + /** + *

    This method sets the {@link LayoutDefinition} key on the given + * UIViewRoot.

    + */ + public static void setLayoutDefinitionKey(UIViewRoot root, String key) { + root.getAttributes().put(LAYOUT_DEFINITION_KEY, key); + } + + + /** + *

    This is the key to be used to store the {@link LayoutDefinition} + * on the ViewRoot in its attribute map.

    + */ + public static final String LAYOUT_DEFINITION_KEY = "_ldKey"; + +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/ComponentType.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/ComponentType.java new file mode 100644 index 0000000..41f9bc1 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/ComponentType.java @@ -0,0 +1,165 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.Serializable; +import java.util.Formatter; + +import com.sun.jsftemplating.util.Util; +import com.sun.jsftemplating.component.factory.ComponentFactory; + + +/** + *

    This class holds information that describes a {@link LayoutComponent} + * type. It provides access to a {@link ComponentFactory} for + * instantiating an instance of a the UIComponent described + * by this descriptor. See the layout.dtd file for more information on + * how to declare types via XML.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ComponentType implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + */ + public ComponentType(String id, String factoryClass) { + if (id == null) { + throw new NullPointerException("'id' cannot be null!"); + } + if (factoryClass == null) { + throw new NullPointerException("'factoryClass' cannot be null!"); + } + _id = id; + _factoryClass = factoryClass; + } + + public ComponentType (String id, String factoryClass, Serializable extraInfo) { + this(id, factoryClass); + this.setExtraInfo(extraInfo); + } + + public String getId() { + return _id; + } + + + /** + *

    This method provides access to the {@link ComponentFactory}.

    + * + * @return The {@link ComponentFactory}. + */ + public ComponentFactory getFactory() { + if (_factory == null) { + _factory = createFactory(); + } + return _factory; + } + + + /** + *

    This method creates a new factory.

    + * + * @return The new {@link ComponentFactory}. + */ + protected ComponentFactory createFactory() { + // Create it... + ComponentFactory factory = null; + try { + Class cls = Util.loadClass(_factoryClass, this); + factory = (ComponentFactory) cls.newInstance(); + } catch (ClassNotFoundException ex) { + throw new RuntimeException(ex); + } catch (InstantiationException ex) { + throw new RuntimeException(ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + + // Set the extraInfo if any... + if (_extraInfo != null) { + factory.setExtraInfo(_extraInfo); + } + + // Return the new ComponentFactory + return factory; + } + + /** + *

    This method allows you to provide extra information that can be + * used to initialize a ComponentType. For example, if + * you wanted to pass in the JSF component type via the property, you + * could do that. That would allow 1 factory class to instatiate + * multiple components based on the JSF component type. However, it + * would require a differnet ComponentType instance for each + * different JSF component type.

    + */ + public void setExtraInfo(Serializable extraInfo) { + _extraInfo = extraInfo; + } + + /** + *

    This method returns the extraInfo that was set for this + * ComponentType. This information will be passed to the + * {@link ComponentFactory} when it is first created. It will only be + * created 1 time, not each time a Component is created.

    + */ + public Serializable getExtraInfo() { + return _extraInfo; + } + + /** + *

    This toString() method produces information about + * this ComponentType.

    + */ + public String toString() { + Formatter println = new Formatter(); + println.format("%-30s %s\n", _id, _factoryClass); + return println.toString(); + } + + + /** + *

    This is the id for the ComponentType.

    + */ + private String _id = null; + + + /** + *

    This is a String className for the Factory.

    + */ + private String _factoryClass = null; + + + /** + *

    The {@link ComponentFactory} that produces the desired + * UIComponent.

    + */ + private transient ComponentFactory _factory = null; + + /** + *

    Extra information associated with this ComponentType.

    + */ + private Serializable _extraInfo = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutAttribute.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutAttribute.java new file mode 100644 index 0000000..a856236 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutAttribute.java @@ -0,0 +1,108 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; + + +/** + *

    This class defines a LayoutAttribute. A LayoutAttribute provides a + * means to write an attribute for the current markup tag. A markup tag + * must be started, but not yet closed for this to work.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutAttribute extends LayoutElementBase implements LayoutElement { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + */ + public LayoutAttribute(LayoutElement parent, String name, String value, String property) { + super(parent, name); + _name = name; + _value = value; + _property = property; + } + + /** + * + */ + public String getName() { + return _name; + } + + /** + * + */ + public String getValue() { + return _value; + } + + /** + * + */ + public String getProperty() { + return _property; + } + + /** + *

    This method displays the text described by this component. If the + * text includes an EL expression, it will be evaluated. It returns + * false to avoid attempting to render children.

    + * + * @param context The FacesContext + * @param component The UIComponent + * + * @return false + */ + protected boolean encodeThis(FacesContext context, UIComponent component) throws IOException { + // Get the ResponseWriter + ResponseWriter writer = context.getResponseWriter(); + + // Render... + Object value = resolveValue(context, component, getValue()); + if ((value != null) && !value.toString().trim().equals("")) { + String name = getName(); + String prop = getProperty(); + if (prop == null) { + // Use the name if property is not supplied + prop = name; + } else if (prop.equals("null")) { + prop = null; + } + writer.writeAttribute(name, value, prop); + } + + // No children + return false; + } + + private String _name = null; + private String _value = null; + private String _property = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutComponent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutComponent.java new file mode 100644 index 0000000..eaad3b4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutComponent.java @@ -0,0 +1,535 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.component.ChildManager; +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.component.TemplateComponent; +import com.sun.jsftemplating.el.VariableResolver; +import com.sun.jsftemplating.layout.LayoutViewHandler; +import com.sun.jsftemplating.layout.ViewRootUtil; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.event.AfterCreateEvent; +import com.sun.jsftemplating.layout.event.AfterEncodeEvent; +import com.sun.jsftemplating.layout.event.BeforeCreateEvent; +import com.sun.jsftemplating.layout.event.BeforeEncodeEvent; +import com.sun.jsftemplating.util.LayoutElementUtil; + + +/** + *

    This class defines a LayoutComponent. A + * LayoutComponent describes a UIComponent to be + * instantiated. The method {@link #getType()} provides a + * {@link ComponentType} descriptor that is capable of providing a + * {@link com.sun.jsftemplating.component.factory.ComponentFactory} + * to perform the actual instantiation. This class also stores properties + * and facets (children) to be set on a newly instantiated instance.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutComponent extends LayoutElementBase implements LayoutElement { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + */ + public LayoutComponent(LayoutElement parent, String id, ComponentType type) { + super(parent, id); + _type = type; + } + + /** + *

    Accessor for type.

    + */ + public ComponentType getType() { + return _type; + } + + /** + *

    Determines if this component should be created even if there is + * already an existing UIComponent. It will "overwrite" + * the existing component if this property is true.

    + */ + public void setOverwrite(boolean value) { + _overwrite = value; + } + + /** + *

    Determines if this component should be created even if there is + * already an existing UIComponent. It will "overwrite" + * the existing component if this property is true.

    + */ + public boolean isOverwrite() { + return _overwrite; + } + + /** + *

    This method adds an option to the LayoutComponent. Options may be + * useful in constructing the LayoutComponent.

    + * + * @param name The name of the option + * @param value The value of the option (may be List or String) + */ + public void addOption(String name, Object value) { + _options.put(name, value); + } + + /** + *

    This method adds all the options in the given Map to the + * {@link LayoutComponent}. Options may be useful in constructing the + * {@link LayoutComponent}.

    + * + * @param map The map of options to add. + */ + public void addOptions(Map map) { + _options.putAll(map); + } + + /** + *

    Accessor method for an option. This method does not evaluate + * expressions.

    + * + * @param name The option name to retrieve. + * + * @return The option value (List or String), or null if not found. + * + * @see #getEvaluatedOption(FacesContext, String, UIComponent) + */ + public Object getOption(String name) { + return _options.get(name); + } + + /** + *

    Accessor method for an option. This method evaluates our own + * expressions (not JSF expressions).

    + * + * @param ctx The FacesContext. + * @param name The option name to retrieve. + * @param component The UIComponent (may be null). + * + * @return The option value (List or String), or null if not found. + * + * @see #getOption(String) + */ + public Object getEvaluatedOption(FacesContext ctx, String name, UIComponent component) { + // Get the option value + Object value = getOption(name); + + // Invoke our own EL. This is needed b/c JSF's EL is designed for + // Bean getters only. It does not get CONSTANTS or pull data from + // other sources (such as session, request attributes, etc., etc.) + // Resolve our variables now because we cannot depend on the + // individual components to do this. We may want to find a way to + // make this work as a regular ValueExpression... but for + // now, we'll just resolve it here. + return VariableResolver.resolveVariables(ctx, this, component, value); + } + + /** + *

    This method returns true/false based on whether the given option + * name has been set.

    + * + * @param name The option name to look for. + * + * @return true/false depending on whether the options exists. + */ + public boolean containsOption(String name) { + return _options.containsKey(name); + } + + /** + *

    This method sets the Map of options.

    + * + * @param options Map of options. + */ + public void setOptions(Map options) { + _options = options; + } + + /** + *

    This method returns the options as a Map. This method does not + * evaluate expressions.

    + * + * @return Map of options. + */ + public Map getOptions() { + return _options; + } + + /** + *

    This method is overriden so that the correct UIComponent can be + * passed into the events. This is important so that correct + * component is searched for "instance" handlers.

    + * + * @param context The FacesContext. + * @param parent The UIComponent. + */ + public void encode(FacesContext context, UIComponent parent) throws IOException { + if (!this.getClass().getName().equals(CLASS_NAME)) { + // The sub-classes of this component shouldn't use this method, + // this is a hack to allow them to use LayoutElementBase.encode + super.encode(context, parent); + return; + } + + // If overwrite... + if (isOverwrite()) { +// FIXME: shouldn't this do a replace, not a remove? Otherwise the order may change + String id = getId(context, parent); + if (parent.getFacets().remove(id) == null) { + UIComponent child = ComponentUtil.getInstance(context).findChild(parent, id, null); + if (child != null) { + // Not a facet, try child... + parent.getChildren().remove(child); + } + } + } + + // Display this UIComponent + // First find the UIComponent + UIComponent childComponent = null; + if (parent instanceof ChildManager) { + // If we have a ChildManager, take advantage of it... + childComponent = ((ChildManager) parent).getChild(context, this); + } else { + // Use local util method for finding / creating child component... + childComponent = getChild(context, parent); + } + + dispatchHandlers(context, BEFORE_ENCODE, + new BeforeEncodeEvent(childComponent)); + + // Add child components... (needs to be done here, LE's can't do it) + // Use check for instance of TC. If present we must instantiate its + // children as they were skipped when the tree was initially created. + if (parent instanceof TemplateComponent) { + // Only do this for TemplateRenderer use-cases (LayoutViewHandler + // does this for pages) + LayoutViewHandler.buildUIComponentTree( + context, childComponent, this); + } + + // Render the child UIComponent + encodeChild(context, childComponent); + + // Invoke "after" handlers + dispatchHandlers(context, AFTER_ENCODE, + new AfterEncodeEvent(childComponent)); + } + + /** + *

    Although this method is part of the interface, it is not used b/c + * I overrode the encode() method which calls this method. This + * method does nothing except satisfy the compiler.

    + */ + public boolean encodeThis(FacesContext context, UIComponent parent) throws IOException { + return false; + } + + /** + *

    This method will find or create a UIComponent as + * described by this LayoutComponent descriptor. If the + * component already exists as a child or facet, it will be returned. + * If it creates a new UIComponent, it will typically be + * added to the given parent UIComponent as a facet (this + * actually depends on the factory that instantiates the + * UIComponent).

    + * + * @param context The FacesContext + * @param parent The UIComponent to serve as the parent to + * search and to store the new UIComponent. + * + * @return The UIComponent requested (found or newly created) + */ + public UIComponent getChild(FacesContext context, UIComponent parent) { + UIComponent childComponent = null; + + // First pull off the id from the descriptor + String id = this.getId(context, parent); + + // We have an id, use it to search for an already-created child + ComponentUtil compUtil = ComponentUtil.getInstance(context); + childComponent = compUtil.findChild(parent, id, id); + if (childComponent != null) { + return childComponent; + } + + // Invoke "beforeCreate" handlers + this.beforeCreate(context, parent); + + // Create UIComponent + childComponent = compUtil.createChildComponent(context, this, parent); + + // Invoke "afterCreate" handlers + this.afterCreate(context, childComponent); + + // Return the newly created UIComponent + return childComponent; + } + + /** + *

    This method retrieves the Handlers for the requested type. But + * also includes any handlers that are associated with the instance + * (i.e. the UIComponent).

    + * + * @param type The type of Handlers to retrieve. + * @param comp The associated UIComponent (or null). + * + * @return A List of Handlers. + */ + public List getHandlers(String type, UIComponent comp) { + // 1st get list of handlers for definition of this LayoutElement + List handlers = null; + + // Now check to see if there are any on the UIComponent + if (comp != null) { + List instHandlers = + (List) comp.getAttributes().get(type); + if ((instHandlers != null) && (instHandlers.size() > 0)) { + // NOTE: Copy b/c this is instance + static + // Add the UIComponent instance handlers + handlers = new ArrayList(instHandlers); + + List defHandlers = getHandlers(type); + if (defHandlers != null) { + // Add the LayoutElement "definition" handlers, if any + handlers.addAll(getHandlers(type)); + } + } + } + if (handlers == null) { + handlers = getHandlers(type); + } + + return handlers; + } + + /** + *

    This method is invoked before the Component described by this + * LayoutComponent is created. This allows handlers registered for + * "beforeCreate" functionality to be invoked.

    + * + * @param context The FacesContext + * + * @return The result of invoking the handlers (null by default) + */ + public Object beforeCreate(FacesContext context, UIComponent parent) { + // Invoke "beforeCreate" handlers + return dispatchHandlers( + context, BEFORE_CREATE, new BeforeCreateEvent(parent)); + } + + /** + *

    This method is invoked after the Component described by this + * LayoutComponent is created. This allows handlers registered for + * "afterCreate" functionality to be invoked.

    + * + * @param context The FacesContext + * + * @return The result of invoking the handlers (null by default) + */ + public Object afterCreate(FacesContext context, UIComponent component) { + // Invoke "afterCreate" handlers + return dispatchHandlers( + context, AFTER_CREATE, new AfterCreateEvent(component)); + } + + /** + *

    This method returns true if the child should be added to the parent + * component as a facet. Otherwise, it returns false indicating that + * it should exist as a real child.

    + * + *

    This value is calculated every time this call is made to allow for + * the context in which the LayoutComponent exists to determine its + * value. If a {@link LayoutFacet} exists as a parent + * {@link LayoutElement}, or a UIViewRoot or + * {@link TemplateComponent} exists as the immediate parent, it will + * return the facet name that should be used. Otherwise, it will + * return null.

    + * + * @param parent This is the parent UIComponent. + * + * @return The facet name if the UIComponent should be added as a facet. + */ + public String getFacetName(UIComponent parent) { + String name = null; + + // First check to see if this LC specifies a different facet name... + name = (String) getOption(FACET_NAME); + if ((name != null) && name.equals(getUnevaluatedId())) { + // No special facet name supplied, don't assume this is a facet yet + name = null; + } + + // Next check to see if we are inside a LayoutFacet + if (name == null) { + LayoutElement parentElt = getParent(); + while (parentElt != null) { + if (parentElt instanceof LayoutFacet) { + // Inside a LayoutFacet, use its name... only if this facet + // is a child of a LayoutComponent (otherwise, it is a + // layout facet used for layout, not for defining a facet + // of a UIComponent) + if (LayoutElementUtil.isLayoutComponentChild(parentElt)) { + name = parentElt.getUnevaluatedId(); + } else { + name = getUnevaluatedId(); + } + if (name == null) { + name = "_noname"; + } + break; + } + if (parentElt instanceof LayoutComponent) { + // No need to process further, this is not a facet child + return null; + } + parentElt = parentElt.getParent(); + } + } + + // If not found yet, check to see if we're at the top... + if (name == null) { + if (parent instanceof TemplateComponent) { + // We don't know if we are adding a child of a + // TemplateComponent from a page, or if the TemplateComponent + // itself has a child... if the TemplateComponent is driving + // the rendering process, then we want this to be a facet. If + // the page is adding a child to a TemplateComponent, we do + // not want this to be a facet. + + // Look to see if the parent LayoutDefinition == the current + // LayoutDefinition. If so, we're "inside" a + // TemplateComponent, not a page. + FacesContext ctx = FacesContext.getCurrentInstance(); + if (((TemplateComponent) parent).getLayoutDefinition(ctx) + == getLayoutDefinition()) { + name = getUnevaluatedId(); + } + } else if ((parent instanceof UIViewRoot) && (ViewRootUtil. + getLayoutDefinition((UIViewRoot) parent) != null)) { + + // NOTE: Only set the name if its a JSFT ViewRoot + name = getUnevaluatedId(); + } + } + + // Return the result + return name; + } + + /** + *

    This method returns a flag that indicates if this + * LayoutComponent is nested (directly or indirectly) + * inside another LayoutComponent. This flag is used + * for such purposes as deciding if "instance" handlers are + * appropriate.

    + * + * @return true if component is nested. + */ + public boolean isNested() { + return _nested; + } + + /** + *

    This method sets the nested flag for this + * LayoutComponent. This method is commonly only called + * from code that constructs the tree of {@link LayoutElement} + * components.

    + * + * @param value The boolean value. + */ + public void setNested(boolean value) { + _nested = value; + } + + /** + *

    Component type

    + */ + private ComponentType _type = null; + + /** + *

    Determines if this component should be created even if there is + * already an existing UIComponent. It will "overwrite" + * the existing component if this property is true. Usually only + * applies when this is used within the context of a + * Renderer.

    + */ + private boolean _overwrite = false; + + /** + *

    Map of options.

    + */ + private Map _options = new HashMap(); + + /** + *

    This is the "type" for handlers to be invoked to handle + * "afterCreate" functionality for this element.

    + */ + public static final String AFTER_CREATE = "afterCreate"; + + /** + *

    This is the "type" for handlers to be invoked to handle + * "beforeCreate" functionality for this element.

    + */ + public static final String BEFORE_CREATE = "beforeCreate"; + + /** + *

    This is the "type" for handlers to be invoked to handle + * "command" functionality for this element.

    + */ + public static final String COMMAND = "command"; + + /** + *

    This defines the property key for specifying the facet name in + * which the component should be stored under in its parent + * UIComponent.

    + */ + public static final String FACET_NAME = "_facetName"; + + /** + *

    This defines the attribute name on the tag that flags that + * duplicate ID's should not be checked for this component. If + * specified on a component, the check will be skipped, regardless + * of the value of the attribute. The attribute name is + * ("skipIdCheck").

    + */ + public static final String SKIP_ID_CHECK= "skipIdCheck"; + + public static final String CLASS_NAME = LayoutComponent.class.getName(); + + /** + *

    The value of the nested property.

    + */ + private boolean _nested = false; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutComposition.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutComposition.java new file mode 100644 index 0000000..eeee5fe --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutComposition.java @@ -0,0 +1,392 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import javax.faces.component.UIComponent; +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.event.EncodeEvent; + + +/** + *

    This concept is borrowed from + * Facelets. A composition delegates to a "template" which performs + * the layout for the content which exists in the body of this + * composition component. The composition may have {@link LayoutDefine}s + * to provide named blocks which the template may "insert" at the + * appropriate place.

    + * + *

    This {@link LayoutElement} implements the behavior not only for + * compositions, but also decorate, and include.

    + * + * @author Jason Lee + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutComposition extends LayoutElementBase { + /** + * @param parent + * @param id + */ + public LayoutComposition(LayoutElement parent, String id) { + super(parent, id); + } + + /** + *

    Constructor.

    + */ + public LayoutComposition(LayoutElement parent, String id, boolean trimming) { + super(parent, id); + this.trimming = trimming; + } + + /** + *

    true if a template filename is required to resolve to + * a valid file. If the template filename is null, this property is + * not used. false if it should be ignored when the does + * not exist. The default is true.

    + */ + public boolean isRequired() { + boolean result = true; + if (required != null) { + Object answer = resolveValue(FacesContext.getCurrentInstance(), null, required); + if (answer != null) { + result = Boolean.parseBoolean(answer.toString()); + } + } + return result; + } + + /** + *

    Setter for the template filename.

    + */ + public void setRequired(String required) { + this.required = required; + } + + /** + *

    Accessor for the template filename.

    + */ + public String getTemplate() { + Object result = resolveValue(FacesContext.getCurrentInstance(), null, template); + return (result == null) ? null : result.toString(); + } + + /** + *

    Setter for the template filename.

    + */ + public void setTemplate(String template) { + this.template = template; + } + + /** + *

    true if all content outside of this LayoutComposition + * should be thrown away.

    + */ + public boolean isTrimming() { + return trimming; + } + + /** + *

    Setter for the trimming property.

    + */ + public void setTrimming(boolean trimming) { + this.trimming = trimming; + } + + @Override + protected boolean encodeThis(FacesContext context, UIComponent component) + throws IOException { + // The child LayoutElements for a LayoutComposition are consumed by + // the template. The LayoutElements consumed here is the template. + String templateName = getTemplate(); + boolean result = true; + if (templateName == null) { + return result; + } + + // Add this to the stack + LayoutComposition.push(context, this); + + // Fire an encode event + dispatchHandlers(context, ENCODE, new EncodeEvent(component)); + + LayoutElement template = null; + try { + template = LayoutDefinitionManager. + getLayoutDefinition(context, templateName); + } catch (LayoutDefinitionException ex) { + if (isRequired()) { + throw ex; + } + + // If the template is optional ignore this error... + } + + // Iterate over children + if (template != null) { + LayoutElement childElt = null; + Iterator it = template.getChildLayoutElements().iterator(); + while (it.hasNext()) { + childElt = it.next(); + childElt.encode(context, component); + } + result = false; + } + + // Pop this from the stack + LayoutComposition.pop(context); + + return result; + } + + /** + *

    This handler pushes a value onto the + * LayoutComposition Stack. In addition + * it puts any parameters that are defined into the global parameter + * Map so EL expressions can test to see if they may + * reference one a composition parameter. However, this + * Map should not be used to determine the value -- + * instead the value should be obtained by looking through the + * Stack of compositions.

    + */ + public static void push(FacesContext context, LayoutElement comp) { + if (comp instanceof LayoutComposition) { + // This should be the case... + Map params = + ((LayoutComposition) comp).getParameters(); + if (params != null) { + // Get the request-scoped global param map... + Map globalParamMap = + LayoutComposition.getGlobalParamMap(context); + + // Iterate over the params in this LayoutComposition and add + // them to the global parameters that we're tracking. This + // will flatten the hierarchy for the parameter values... but + // that's ok, b/c we don't use this for obtaining the values + // (normally), we use it to quickly detect if there are values. + // We'll search the composition stack to actually obtain the + // values. + Iterator> it = + params.entrySet().iterator(); + Map.Entry entry = null; + while (it.hasNext()) { + entry = it.next(); + globalParamMap.put(entry.getKey(), entry.getValue()); + } + } + } + getCompositionStack(context).push(comp); + } + + /** + *

    This handler pops a value off the + * LayoutComposition Stack.

    + */ + public static LayoutElement pop(FacesContext context) { + return getCompositionStack(context).pop(); + } + + /** + *

    This method returns the Stack used to keep track of + * the {@link LayoutComposition}s that are used.

    + */ + public static Stack getCompositionStack(FacesContext context) { + Map requestMap = (context == null) ? + getTestMap() : context.getExternalContext().getRequestMap(); + Stack stack = (Stack) + requestMap.get(COMPOSITION_STACK_KEY); + if (stack == null) { + stack = new Stack(); + requestMap.put(COMPOSITION_STACK_KEY, stack); + } + return stack; + } + + /** + *

    This method retrieves a Map from the request scope for storing + * ui:param NVPs. If the Map doesn't exist, it will be + * created.

    + */ + public static Map getGlobalParamMap(FacesContext context) { + // First get the requestMap + Map requestMap = + context.getExternalContext().getRequestMap(); + Map paramMap = (Map) + requestMap.get(GLOBAL_PARAM_MAP_KEY); + if (paramMap == null) { + // Hasn't been created yet, create it + paramMap = new HashMap(); + requestMap.put(GLOBAL_PARAM_MAP_KEY, paramMap); + } + return paramMap; + } + + /** + *

    This method returns a Map that may be used to test + * this code outside JSF.

    + */ + private static Map getTestMap() { +// FIXME: Shouldn't we mock up the test environment instead of changing the code here? + if (_testMap == null) { + _testMap = new HashMap(); + } + return _testMap; + } + + /** + *

    This method allows the composition stack to be set directly. + * Normally this isn't needed, but if a seperate walk of the tree + * must be done in the middle of an existing walk, this may be + * necessary to reset and restore the Stack.

    + */ + public static Stack setCompositionStack(FacesContext context, Stack stack) { + Map requestMap = context.getExternalContext().getRequestMap(); + requestMap.put(COMPOSITION_STACK_KEY, stack); + return stack; + } + + /** + *

    This method searches the given the entire stack for a + * template param with the given name.

    + * + *

    A "template param" is a name-value-pair associated with a + * {@link LayoutComposition}. This enables overridable values to be + * set on a LayoutComposition and consumed by the templates. This is + * similar to a ui:define, except for values instead of + * UIComponents.

    + * + * @param eltList The List of LayoutCompositions in which + * to search (must be non-null, NPE will be thrown). + * @param name The name of the parameter to look for. + */ + public static Object findTemplateParam(List eltList, String name) { +// FIME: Can I make this return a String? If this is at create time I should still have #{} or maybe ${} + Iterator stackIt = eltList.iterator(); + Object val = null; + LayoutElement elt = null; + LayoutComposition comp = null; + while (stackIt.hasNext()) { + elt = stackIt.next(); + if (elt instanceof LayoutComposition) { + // It should always be a LayoutComposition, however, I want + // to be safe in case things change in the future. + comp = (LayoutComposition) elt; + if ((val = comp.getParameter(name)) != null) { + break; + } + } + } + + // Return the value (if found) + return val; + } + + /** + *

    This method returns the Map of parameter values, or + * null if there are no parameter values for this + * LayoutComposition.

    + */ + protected Map getParameters() { + return _params; + } + + /** + *

    This method returns the parameter value for the requested + * parameter, or null if the requested parameter does + * not exist.

    + */ + public Object getParameter(String name) { + Object value = null; + if (_params != null) { + value = _params.get(name); + } + return value; + } + + /** + *

    This method sets the given parameter name with the given parameter + * value.

    + */ + public void setParameter(String name, Object value) { + if (_params == null) { + _params = new HashMap(); + } + _params.put(name, value); + } + + + private static final long serialVersionUID = 2L; + + /** + *

    This is the key used to store the LayoutComposition + * stack.

    + */ + private static final String COMPOSITION_STACK_KEY = "_composition"; + + /** + *

    This is the key used to store the ui:param NVPs to assist in + * determining if an EL is referencing one. It also may be used in + * somone attempts to locate a ui:param after the composition stack + * is no longer available (don't do that!).

    + */ + private static final String GLOBAL_PARAM_MAP_KEY = "_uiparamCacheMap"; + + /** + *

    This Map exists to allow test cases to run w/o an ExternalContext + * "request map."

    + */ + private static Map _testMap = null; + + /** + *

    This is a Map of parameters that may be passed from + * this LayoutComposition to the template.

    + */ + private Map _params = null; + + /** + *

    Flag to indicate that whether an exception should be thrown if the + * template is not found.

    + */ + private String required = null; + + /** + *

    The filename of the template.

    + */ + private String template = null; + + /** + *

    True if trimming should occur.

    + */ +// FIXME: This info is only important at read-time, this probably should NOT exist + private boolean trimming = true; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutDefine.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutDefine.java new file mode 100644 index 0000000..3cf580e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutDefine.java @@ -0,0 +1,53 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +/** + *

    This {@link LayoutElement} provides a means to identify a portion of + * the LayoutDefinition tree by name (id). This is used by + * {@link LayoutInsert} to include portions of the tree defined elsewhere + * at the location of the {@link LayoutInsert}.

    + * + * @author Jason Lee + */ +public class LayoutDefine extends LayoutElementBase { + private static final long serialVersionUID = 1L; + + /** + * @param parent + * @param id + */ + public LayoutDefine(LayoutElement parent, String id) { + super(parent, id); + } + + @Override + protected boolean encodeThis(FacesContext context, UIComponent component) throws IOException { + return true; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutDefinition.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutDefinition.java new file mode 100644 index 0000000..d91e2b1 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutDefinition.java @@ -0,0 +1,420 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.lang.reflect.Method; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.component.TemplateComponent; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition; +import com.sun.jsftemplating.layout.event.DecodeEvent; +import com.sun.jsftemplating.layout.event.InitPageEvent; +import com.sun.jsftemplating.util.Util; + +/** + *

    This represents the top-level {@link LayoutElement}, it is the + * container for every other {@link LayoutElement}. By itself, it has no + * functionality. Its purpose in life is to group all top-level child + * {@link LayoutElement}s. LayoutDefintion objects can be registered + * with the + * {@link com.sun.jsftemplating.layout.LayoutDefinitionManager}.

    + * + *

    This class provide a helper method + * {@link #getChildLayoutElementById(FacesContext, String, LayoutElement, UIComponent)} + * which will search recursively for the given child LayoutElement by id.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutDefinition extends LayoutElementBase { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + */ + public LayoutDefinition(String id) { + // LayoutDefinition objects do not have a parent + super(null, id); + + // Set the default StaticText ComponentType + addComponentType(new ComponentType( + STATIC_TEXT_TYPE, STATIC_TEXT_FACTORY_CLASS_NAME)); + } + + /** + *

    This method returns the Map containing the + * {@link ComponentType}s. It ensures that the Map is + * not null.

    + */ + protected Map getComponentTypes() { + if (_types == null) { + _types = new HashMap(); + } + return _types; + } + + /** + *

    Retrieve a {@link ComponentType} by typeID.

    + * + * @param typeID The key used to retrieve the ComponentType + * + * @return The requested ComponentType or null + * + * @deprecated Reader's should use global {@link ComponentType}s (see + * {@link com.sun.jsftemplating.layout.LayoutDefinitionManager#getGlobalComponentType(FacesContext, String)}) + * or should cache {@link ComponentType}s locally, this information is + * not needed in the LayoutDefinition. + */ + public ComponentType getComponentType(String typeID) { + return getComponentTypes().get(typeID); + } + + + /** + *

    This will add the given ComponentType to the map of + * registered ComponentType's. It will use the + * ComponentType ID as the key to the Map. + * This means that if a ComponentType with the same ID had + * previously been registered, it will be replaced with the + * ComponentType passed in.

    + * + * @param type The ComponentType. + * + * @deprecated Reader's should use global {@link ComponentType}s (see + * {@link com.sun.jsftemplating.layout.LayoutDefinitionManager#addGlobalComponentType(FacesContext, ComponentType)}) + * or should cache {@link ComponentType}s locally, this information is + * not needed in the LayoutDefinition. + */ + public void addComponentType(ComponentType type) { + getComponentTypes().put(type.getId(), type); + } + + /** + *

    This method adds a {@link Resource}. These resources should be + * added to the request scope when this component is used. This is + * mainly used for ResourceBundles (at this time).

    + * + * @param res The {@link Resource} to associate with the + * LayoutDefinition. + */ + public void addResource(Resource res) { + _resources.add(res); + } + + /** + *

    This method returns a List of {@link Resource} objects.

    + * + * @return This method returns a List of {@link Resource} objects. + */ + public List getResources() { + return _resources; + } + + /** + *

    This method allows the List of {@link Resource}s to + * be set.

    + * + * @param resources List to {@link Resource}s. + */ + public void setResources(List resources) { + _resources = resources; + } + + /** + *

    This method searches for the requested {@link LayoutComponent} by + * id.

    + * + * @param context FacesContext + * @param id id to look for + * @param parent Search starts from this {@link LayoutElement} + * @param parentComponent Parent UIComponent + * + * @return The matching {@link LayoutElement} if found, null otherwise. + */ + public static LayoutElement getChildLayoutElementById(FacesContext context, String id, LayoutElement parent, UIComponent parentComponent) { + // NOTE: I may want to optimize this by putting all values in a Map so + // NOTE: that I don't have to do this search. + + // Make sure this isn't what we're looking for + if (parent.getId(context, parentComponent).equals(id)) { + return parent; + } + + // Not 'this' so lets check the children + Iterator it = parent.getChildLayoutElements().iterator(); + LayoutElement elt = null; + while (it.hasNext()) { + elt = getChildLayoutElementById( + context, id, it.next(), parentComponent); + if (elt != null) { + // Found it! + return elt; + } + } + + // Not found... + return null; + } + + + /** + *

    Retrieve an attribute by key.

    + * + * @param key The key used to retrieve the attribute + * + * @return The requested attribute or null. + public Object getAttribute(String key) { + return _attributes.get(key); + } + */ + + + /** + *

    Associate the given key with the given Object as an attribute.

    + * + * @param key The key associated with the given object (if this key + * is already in use, it will replace the previously set attribute + * object). + * + * @param value The Object to store. + public void setAttribute(String key, Object value) { + _attributes.put(key, value); + } + */ + + /** + *

    This method sets a locally defined {@link HandlerDefinition}.

    + */ + public void setHandlerDefinition(String key, HandlerDefinition value) { + _attributes.put(key, value); + } + + /** + *

    This method accesses a locally defined {@link HandlerDefinition}.

    + */ + public HandlerDefinition getHandlerDefinition(String key) { + return _attributes.get(key); + } + + /** + *

    This function overrides the superclass in order to call + * encodeBegin / encodeEnd on the UIViewRoot (and only for UIViewRoot + * instances). This is especially important for Ajax requests.

    + */ + @Override + public void encode(FacesContext context, UIComponent component) throws IOException { + if (component instanceof UIViewRoot) { + component.encodeBegin(context); +// FIXME: For now I am treating "@all" Ajax requests as normal requests... +// FIXME: Otherwise the partialviewcontext tries to render the whole view, and +// FIXME: fails b/c JSFT may use Facets for top-level components. Need to find +// FIXME: a better way to handle this. + if (context.getPartialViewContext().isPartialRequest() && !context.getPartialViewContext().isRenderAll()) { + // JSF is now overriding this, so this is required... + component.encodeChildren(context); + } else { + // This is not an ajax request... behave normal + super.encode(context, component); + } + component.encodeEnd(context); + } else { + super.encode(context, component); + } + } + + /** + *

    The LayoutDefinition does not encode anything for + * itself, this method simply returns true.

    + * + * @param context The FacesContext. + * @param component The UIComponent. + * + * @return true. + */ + protected boolean encodeThis(FacesContext context, UIComponent component) throws IOException { + return true; + } + + /** + *

    This method retrieves the Handlers for the requested type. But + * also includes any handlers that are associated with the instance + * (i.e. the UIComponent).

    + * + * @param type The type of Handlers to retrieve. + * @param comp The associated UIComponent (or null). + * + * @return A List of Handlers. + */ + public List getHandlers(String type, UIComponent comp) { + // 1st get list of handlers for definition of this LayoutElement + List handlers = null; + + // Now check to see if there are any on the UIComponent (NOTE: We do + // not pull off handlers if the parent is a TemplateComponent b/c it + // is the responsibility of the parent class to invoke handlers via + // its LayoutComponent. If we do it here, it will happen 2x.) + if ((comp != null) + && (!(comp.getParent() instanceof TemplateComponent))) { + List instHandlers = + (List) comp.getAttributes().get(type); + if ((instHandlers != null) && (instHandlers.size() > 0)) { + // NOTE: Copy b/c this is instance + static + // Add the UIComponent instance handlers + handlers = new ArrayList(instHandlers); + + List defHandlers = getHandlers(type); + if (defHandlers != null) { + // Add the LayoutElement "definition" handlers, if any + handlers.addAll(getHandlers(type)); + } + } + } + if (handlers == null) { + handlers = getHandlers(type); + } + + return handlers; + } + + /** + *

    This decode method invokes any registered {@link #DECODE} + * handlers.

    + * + * @param context The FacesContext. + * @param component The UIComponent. + */ + public void decode(FacesContext context, UIComponent component) { + // Invoke "decode" handlers + dispatchHandlers(context, DECODE, new DecodeEvent(component)); + } + + /** + *

    This method is responsible for dispatching the "initPage" handlers + * associated with this LayoutDefinition (if any).

    + * + *

    The source passed in should be the + * UIViewRoot. However, it is expected that in most + * cases this will not be available. It is reasonable for this to be + * null.

    + * + *

    If the FacesContext provided is null, this method + * will simply return.

    + */ + public void dispatchInitPageHandlers(FacesContext ctx, Object source) { + // Sanity check (this may happen if invoked outside JSF)... + if (ctx == null) { + // Do nothing... + return; + } + + // Check to see if we've already done this... + if (isInitPageExecuted(ctx)) { + // We've already init'd this request, do nothing + return; + } + + // Dispatch Handlers + dispatchHandlers(ctx, INIT_PAGE, new InitPageEvent(source)); + + // Flag request as having processed the initPage handlers + setInitPageExecuted(ctx, Boolean.TRUE); + } + + /** + *

    This method checks to see if the initPage event has fired yet + * for this request.

    + */ + public boolean isInitPageExecuted(FacesContext ctx) { + Map reqAtts = ctx.getExternalContext().getRequestMap(); + String key = INIT_PAGE_PREFIX + getId(ctx, (UIComponent) null); + return Boolean.TRUE.equals(reqAtts.get(key)); + } + + /** + *

    This method marks the initPage event as fired for this request.

    + */ + public void setInitPageExecuted(FacesContext ctx, boolean value) { + String key = INIT_PAGE_PREFIX + getId(ctx, (UIComponent) null); + ctx.getExternalContext().getRequestMap().put(key, value); + } + + + /** + * + */ + private static final String INIT_PAGE_PREFIX = "__ip"; + + /** + *

    This is the "type" for handlers to be invoked to handle "decode" + * functionality for this element.

    + */ + public static final String DECODE = "decode"; + + /** + *

    This is the "type" for handlers to be invoked to handle "initPage" + * functionality for this element.

    + */ + public static final String INIT_PAGE = "initPage"; + + /** + *

    This is a hard-coded LayoutComponent type. By default it + * corresponds to + * {@link com.sun.jsftemplating.component.factory.basic.StaticTextFactory}.

    + */ + public static final String STATIC_TEXT_TYPE = + "staticText"; + + /** + *

    This is the full classname of the default StaticTextFactory.

    + */ + public static final String STATIC_TEXT_FACTORY_CLASS_NAME = + "com.sun.jsftemplating.component.factory.basic.StaticTextFactory"; + + /** + *

    This is a list of Resource objects. These resources are to be + * added to the Request scope when this LayoutDefinition + * is used.

    + */ + private List _resources = new ArrayList(); + + /** + *

    Map of types. This information is needed to instantiate + * UIComponents.

    + */ + private Map _types = null; + + /** + *

    Map of attributes. Attributes can be used to store extra + * information about the LayoutDefinition.

    + */ + private Map _attributes = new HashMap(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutElement.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutElement.java new file mode 100644 index 0000000..32253e8 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutElement.java @@ -0,0 +1,194 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; +import java.util.EventObject; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; + +/** + *

    This interface is declares the methods required to be a + * LayoutElement. A LayoutElement is the building block of the tree + * structure which defines a layout for a particular component. There are + * different implementations of LayoutElement that provide various + * different types of functionality and data. Some examples are:

    + * + *
    • Conditional ({@link LayoutIf}), this allows portions of the + * layout tree to be conditionally rendered.
    • + *
    • Iterative ({@link LayoutWhile}), this allows portions of the + * layout tree to be iteratively rendered.
    • + *
    • UIComponent ({@link LayoutComponent}), this allows concrete + * UIComponents to be used. If the component doesn't already exist, + * it will be created automatically.
    • + *
    • Facet place holders ({@link LayoutFacet}), this provides a means + * to specify where a facet should be rendered. It is not a facet + * itself but where a facet should be drawn. However, in addition, + * it may specify a default value if no facet was provided.
    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface LayoutElement extends java.io.Serializable { + + /** + * This method is used to add a LayoutElement. LayoutElements should be + * added sequentially in the order in which they are to be rendered. + */ + public void addChildLayoutElement(LayoutElement element); + + + /** + * This method returns the child LayoutElements as a List of LayoutElement. + * + * @return List of LayoutElements + */ + public List getChildLayoutElements(); + + /** + *

    This method returns the requested child {@link LayoutElement} by + * id.

    + * + * @param id The id of the child to find and return. + * + * @return The requested {@link LayoutElement}; null if not + * found. + */ + public LayoutElement getChildLayoutElement(String id); + + /** + *

    This method searches the LayoutElement tree + * breadth-first for a LayoutElement with the given + * id.

    + */ + public LayoutElement findLayoutElement(String id); + + /** + * This method returns the parent LayoutElement. + * + * @return parent LayoutElement + */ + public LayoutElement getParent(); + + + /** + * This method returns the LayoutDefinition. If unable to, it will throw + * an Exception. + * + * @return The LayoutDefinition + */ + public LayoutDefinition getLayoutDefinition(); + + + /** + *

    This method retrieves the {@link Handler}s for the requested + * type.

    + * + * @param type The event type of {@link Handler}s to retrieve. + * + * @return A List of {@link Handler}s. + */ + public List getHandlers(String type); + + /** + *

    This method retrieves the {@link Handler}s for the requested + * type. This method is unique in that it looks at the + * UIComponent passed in to see if there are + * {@link Handler}s defined on it (instance handlers vs. those + * defined on the LayoutElement.

    + * + * @param type The event type of {@link Handler}s to retrieve. + * @param comp The associated UIComponent (or null). + * + * @return A List of {@link Handler}s. + */ + public List getHandlers(String type, UIComponent comp); + + /** + *

    This method provides access to the "handlersByType" + * Map.

    + */ + public Map> getHandlersByTypeMap(); + + /** + *

    This method associates 'type' with the given list of Handlers.

    + * + * @param type The String type for the List of Handlers + * @param handlers The List of Handlers + */ + public void setHandlers(String type, List handlers); + + /** + * Accessor method for id. This should always return a non-null value, + * it may return "" if id does not apply. + * + * @return a non-null id + */ + public String getId(FacesContext context, UIComponent parent); + + /** + *

    This method generally should not be used. It does not resolve + * expressions. Instead use + * {@link #getId(FacesContext, UIComponent)}.

    + * + * @return The unevaluated id. + */ + public String getUnevaluatedId(); + + /** + * This method performs any encode action for this particular + * LayoutElement. + * + * @param context The FacesContext + * @param component The UIComponent + */ + public void encode(FacesContext context, UIComponent component) throws IOException; + + /** + * + */ + public Object dispatchHandlers(HandlerContext handlerCtx, List handlers); + + /** + *

    This method iterates over the handlers and executes each one. A + * HandlerContext will be created to pass to each Handler. The + * HandlerContext object is reused across all Handlers that are + * invoked; the setHandler(Handler) method is invoked with the + * correct Handler descriptor before the handler is executed.

    + * + * @param context The FacesContext + * @param eventType The event type which is being fired + * @param event An optional EventObject providing more detail + * + * @return By default, (null) is returned. However, if any of the + * handlers produce a non-null return value, then the value from + * the last handler to produces a non-null return value is + * returned. + */ + public Object dispatchHandlers(FacesContext context, String eventType, EventObject event); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutElementBase.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutElementBase.java new file mode 100644 index 0000000..6c435a9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutElementBase.java @@ -0,0 +1,608 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.EventObject; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContextImpl; +import com.sun.jsftemplating.layout.event.AfterEncodeEvent; +import com.sun.jsftemplating.layout.event.BeforeEncodeEvent; +import com.sun.jsftemplating.layout.event.EncodeEvent; +import com.sun.jsftemplating.util.LayoutElementUtil; + + +/** + *

    This class provides some common functionality between the various types + * of {@link LayoutElement}s. It is the base class of most + * implementations (perhaps all).

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public abstract class LayoutElementBase implements LayoutElement { + + /** + *

    Constructor.

    + * + * @param parent The parent LayoutElement + * @param id Identifier for this LayoutElement + */ + protected LayoutElementBase(LayoutElement parent, String id) { + setParent(parent); + _id = id; + } + + + /** + *

    This method is used to add a {@link LayoutElement}. + * {@link LayoutElement}s should be added sequentially in the order + * in which they are to be rendered.

    + * + * @param element The {@link LayoutElement} to add as a child. + */ + public void addChildLayoutElement(LayoutElement element) { + _layoutElements.add(element); + } + + + /** + *

    This method returns the {@link LayoutElement}s as a + * List of {@link LayoutElement}.

    + * + * @return List of {@link LayoutElement}s. + */ + public List getChildLayoutElements() { + return _layoutElements; + } + + /** + *

    This method returns the requested child {@link LayoutElement} by + * id.

    + * + * @param id The id of the child to find and return. + * + * @return The requested {@link LayoutElement}; null if not + * found. + */ + public LayoutElement getChildLayoutElement(String id) { + Iterator it = getChildLayoutElements().iterator(); + LayoutElement elt = null; + while (it.hasNext()) { + elt = it.next(); + if (id.equals(elt.getUnevaluatedId())) { + return elt; + } + } + return null; + } + + /** + *

    This method searches the LayoutElement tree + * breadth-first for a LayoutElement with the given + * id.

    + */ + public LayoutElement findLayoutElement(String id) { + if (id == null) { + return null; + } + +// FIXME: Generalize this code so we can use it when creating the tree as well as searching for stuff. + + // First look at all the immediate children, save compositions if + // we encounter them. + List children = getChildLayoutElements(); + for (LayoutElement elt : children) { + if (id.equals(elt.getUnevaluatedId())) { + // Found it! + return elt; + } + } + + // First make sure we aren't a LayoutComposition ourselves + LayoutElement result = null; + FacesContext context = FacesContext.getCurrentInstance(); + if (this instanceof LayoutComposition) { + // Add LayoutComposition to the stack + LayoutComposition.push(context, this); + + // Find the new LD tree... + LayoutDefinition def = LayoutDefinitionManager.getLayoutDefinition( + context, ((LayoutComposition) this).getTemplate()); + + // Recurse... + result = def.findLayoutElement(id); + LayoutComposition.pop(context); + } + + // Next we need to walk deeper... + for (LayoutElement elt : children) { + if ((elt instanceof LayoutComposition) + && (((LayoutComposition) elt).getTemplate() != null)) { + // Add LayoutComposition to the stack + LayoutComposition.push(context, elt); + + // Find the new LD tree... + LayoutDefinition def = LayoutDefinitionManager.getLayoutDefinition( + context, ((LayoutComposition) elt).getTemplate()); + + // Recurse... + result = def.findLayoutElement(id); + LayoutComposition.pop(context); + } else if (elt instanceof LayoutInsert) { + // FIXME: Look through Stack/List of compositions we've already walked for inserted value. + } else { + // Just walk its children... + result = elt.findLayoutElement(id); + } + if (result != null) { +// FIXME: Manage stack!!! + break; + } + } + + // Return result if found + return result; + } + + /** + *

    This method walks to the top-most {@link LayoutElement}, which + * should be a {@link LayoutDefinition}. If not, it will throw an + * exception.

    + * + * @return The {@link LayoutDefinition}. + */ + public LayoutDefinition getLayoutDefinition() { + // Find the top-most LayoutElement + LayoutElement cur = this; + while (cur.getParent() != null) { + cur = cur.getParent(); + } + + // Incomplete LayoutElement trees may not have a LD at the root, make + // sure we have a LD. + if (!(cur instanceof LayoutDefinition)) { + // Not a LD, there is no LD... set return value to null + cur = null; + } + + // This should be the LayoutDefinition, return it + return (LayoutDefinition) cur; + } + + + /** + *

    This method returns the parent {@link LayoutElement}.

    + * + * @return parent LayoutElement + */ + public LayoutElement getParent() { + return _parent; + } + + + /** + *

    This method sets the parent {@link LayoutElement}.

    + * + * @param parent Parent {@link LayoutElement}. + */ + protected void setParent(LayoutElement parent) { + _parent = parent; + } + + + /** + *

    Accessor method for id. This returns a non-null value, it may + * return "" if id is not set or does not apply.

    + * + *

    This method will also NOT resolve EL strings.

    + * + * @return a non-null id + */ + private String getId() { + if ((_id == null) || (_id == "")) { + // Ensure we ALWAYS have an id, however, generating ids is + // potentially dangerous because the results may not be the same + // always. Effort has been taken to avoid most problems, though. + _id = LayoutElementUtil.getGeneratedId((String) null); + } + return _id; + } + + /** + *

    This method generally should not be used. It does not resolve + * expressions. Instead use + * {@link #getId(FacesContext, UIComponent)}.

    + * + * @return The unevaluated id. + */ + public String getUnevaluatedId() { + return getId(); + } + + /** + *

    Accessor method for id. This returns a non-null value, it may + * return "" if id is not set or does not apply.

    + * + *

    This method will also attempt to resolve EL strings.

    + * + * @param context The FacesContext + * @param parent The parent UIComponent. This is used + * because the current UIComponent is typically + * unknown (or not even created yet). + * + * @return A non-null id. + */ + public String getId(FacesContext context, UIComponent parent) { + // Evaluate the id... + Object value = resolveValue(context, parent, getId()); + + // Return the result + return (value == null) ? "" : value.toString(); + } + + /** + *

    This method will attempt to resolve EL strings in the given + * value.

    + * + * @param context The FacesContext + * @param parent The parent UIComponent. This is used + * because the current UIComponent is typically + * unknown (or not even created yet). + * @param value The String to resolve + * + * @return The evaluated value (may be null). + */ + public Object resolveValue(FacesContext context, UIComponent parent, Object value) { + return ComponentUtil.getInstance(context).resolveValue(context, this, parent, value); + } + + /** + *

    This method allows each LayoutElement to provide it's own encode + * functionality. If the {@link LayoutElement} should render its + * children, this method should return true. Otherwise, this method + * should return false.

    + * + * @param context The FacesContext + * @param component The UIComponent + * + * @return true if children are to be rendered, false otherwise. + */ + protected abstract boolean encodeThis(FacesContext context, UIComponent component) throws IOException; + + /** + *

    This is the base implementation for encode. Typically each type of + * LayoutElement wants to do something specific then conditionally have + * its children rendered. This method invokes the abstract method + * "encodeThis" to do specific functionality, it the walks the children + * and renders them, if encodeThis returns true. It skips the children + * if encodeThis returns false.

    + * + *

    NOTE: Some subclasses override this method, be careful when + * changing/adding to this code.

    + * + * @param context The FacesContext + * @param component The UIComponent + */ + public void encode(FacesContext context, UIComponent component) throws IOException { + // Invoke "before" handlers + Object result = dispatchHandlers(context, BEFORE_ENCODE, + new BeforeEncodeEvent(component)); + + if ((result != null) && (result.toString().equals("false"))) { + // Skip... + return; + } + + // Do LayoutElement specific stuff... + boolean renderChildren = encodeThis(context, component); + +// FIXME: Consider buffering HTML and passing to "endDisplay" handlers... +// FIXME: Storing in the EventObject may be useful if we go this route. + + // Perhaps we want our own Response writer to buffer children? + //ResponseWriter out = context.getResponseWriter(); + + // Conditionally render children... + if (renderChildren) { + result = dispatchHandlers(context, ENCODE, + new EncodeEvent(component)); + + // Iterate over children + LayoutElement childElt = null; + Iterator it = getChildLayoutElements().iterator(); + while (it.hasNext()) { + childElt = it.next(); + childElt.encode(context, component); + } + } + + // Invoke "after" handlers + result = dispatchHandlers(context, AFTER_ENCODE, + new AfterEncodeEvent(component)); + } + + + /** + *

    This method iterates over the {@link Handler}s and executes each + * one. A {@link HandlerContext} will be created to pass to each + * {@link Handler}. The {@link HandlerContext} object is reused + * across all {@link Handler}s that are invoked; the + * {@link HandlerContext#setHandler(Handler)} method is invoked with + * the correct {@link Handler} descriptor before the handler is + * executed.

    + * + * @param context The FacesContext + * @param eventType The event type which is being fired + * @param event An optional EventObject + * + * @return By default, (null) is returned. However, if any of the + * {@link Handler}s produce a non-null return value, the value + * from the last {@link Handler} to produces a non-null return + * value is returned. + */ + public Object dispatchHandlers(FacesContext context, String eventType, EventObject event) { + // Get the handlers for this eventType + Object eventObj = event.getSource(); + if (!(eventObj instanceof UIComponent)) { + eventObj = null; + } + List handlers = getHandlers(eventType, (UIComponent) eventObj); + + // Make sure we have something to do... + if (handlers == null) { + return null; + } + + // Create a HandlerContext + HandlerContext handlerContext = + createHandlerContext(context, event, eventType); + + // This method is broken down so that recursion is easier + return dispatchHandlers(handlerContext, handlers); + } + + /** + *

    As currently implemented, this method is essentially a utility + * method. It dispatches the given List of {@link Handler}s. + * This may be available as a static method in the future.

    + */ + public Object dispatchHandlers(HandlerContext handlerCtx, List handlers) { + FacesContext ctx = handlerCtx.getFacesContext(); + Object retVal = null; + Object result = null; + // Only check for renderResponse if we're not already doing it + boolean checkRenderResp = !ctx.getRenderResponse(); + + // Iterate through the handlers... + for (Handler handler : handlers) { + if (ctx.getResponseComplete() || + (checkRenderResp && ctx.getRenderResponse())) { + // If we shouldn't continue, just return the result. + // Should we throw an AbortProcessingException + return result; + } + handlerCtx.setHandler(handler); + try { + // Delegate to the Handler to perform invocation + retVal = handler.invoke(handlerCtx); + } catch (Exception ex) { + throw new RuntimeException( + ex.getClass().getName() + " while attempting to " + + "process a '" + handlerCtx.getEventType() + + "' event for '" + getId() + "'.", ex); + } + + // Check for return value + if (retVal != null) { + result = retVal; + } + } + + // Return the return value (null by default) + return result; + } + + /** + *

    This method is responsible for creating a new HandlerContext. It + * does not set the Handler descriptor. This is done right before a + * Handler is invoked. This allows the HandlerContext object to be + * reused.

    + * + * @param context The FacesContext + */ + protected HandlerContext createHandlerContext(FacesContext context, EventObject event, String eventType) { + return new HandlerContextImpl(context, this, event, eventType); + } + + /** + *

    This method retrieves the {@link Handler}s for the requested type.

    + * + * @param type The type of {@link Handler}s to retrieve. + * + * @return A List of {@link Handler}s. + */ + public List getHandlers(String type) { + return _handlersByType.get(type); + } + + /** + *

    This method provides access to the "handlersByType" + * Map.

    + */ + public Map> getHandlersByTypeMap() { + return _handlersByType; + } + + /** + *

    This method provides a means to set the "handlersByType" Map. + * Normally this is done for each type individually via + * {@link #setHandlers(String, List)}. This Map may not be null (null + * will be ignored) and should contain entries that map to + * Lists of {@link Handler}s. + */ + public void setHandlersByTypeMap(Map> map) { + if (map != null) { + _handlersByType = map; + } + } + + /** + *

    This method retrieves the {@link Handler}s for the requested + * type.

    + * + * @param type The type of Handlers to retrieve. + * @param comp The associated UIComponent (or null). + * + * @return A List of {@link Handler}s. + */ + public List getHandlers(String type, UIComponent comp) { + // 1st get list of handlers for definition of this LayoutElement + List handlers = getHandlers(type); + + // NOTE: At this point, very few types should support "instance" + // NOTE: handlers (LayoutComponent, LayoutDefinition, more??). To + // NOTE: support them, the future, the specific LayoutElement subclass + // NOTE: will have to deal with this. For example, LayoutComponent + // NOTE: "instance" handlers are dealt with in LayoutComponent (it + // NOTE: overrides this method). + + return handlers; + } + + /** + *

    This method associates 'type' with the given list of + * {@link Handler}s.

    + * + * @param type The String type for the List of {@link Handler}s + * @param handlers The List of {@link Handler}s + */ + public void setHandlers(String type, List handlers) { + _handlersByType.put(type, handlers); + } + + /** + *

    This method is a convenience method for encoding the given + * UIComponent. It calls the appropriate encoding + * methods on the component and calls itself recursively for all + * UIComponent children that do not render their own + * children.

    + * + * @param context FacesContext + * @param component UIComponent to encode + */ + public static void encodeChild(FacesContext context, UIComponent component) throws IOException { + if (!component.isRendered()) { + return; + } + + /******* REMOVE THIS IF TABLE IS EVER FIXED TO WORK RIGHT *******/ +/* + * This code is removed b/c of the way the Table code is designed. It + * needs to recalculate the clientId all the time. Rather than deal with + * this in the table code, the design requires that every component + * regenerate its clientId every time it is rendered. Hopefully the Table + * code will be rewritten to not require this, or to do this task itself. + * + * For now, I will avoid doing the "right" thing and reset the id blindly. + * This causes the clientId to be erased and regenerated. + */ + String id = component.getId(); + if (id != null) { + component.setId(id); + } + /******* REMOVE THIS IF TABLE IS EVER FIXED TO WORK RIGHT *******/ + +// FIXME: May have to change to encodeAll()!!! + component.encodeBegin(context); + if (component.getRendersChildren()) { + component.encodeChildren(context); + } else { + Iterator it = component.getChildren().iterator(); + while (it.hasNext()) { + encodeChild(context, it.next()); + } + } + component.encodeEnd(context); + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + LayoutElementUtil.dumpTree(this, buf, ""); + + return buf.toString(); + } + + /** + * List of child LayoutElements (if, facet, UIComponents, etc.) + */ + private List _layoutElements = new ArrayList(); + + /** + * The parent LayoutElement. This will be null for the LayoutDefinition. + */ + private LayoutElement _parent = null; + + /** + *

    Map containing Lists of + * {@link Handler}s.

    + */ + private Map> _handlersByType = new HashMap>(); + + /** + * This stores the id for the LayoutElement + */ + private String _id = null; + + /** + *

    This is the "type" for handlers to be invoked after the encoding + * of this element.

    + */ + public static final String AFTER_ENCODE = "afterEncode"; + + /** + *

    This is the "type" for handlers to be invoked before the encoding + * of this element.

    + */ + public static final String BEFORE_ENCODE = "beforeEncode"; + + /** + *

    This is the "type" for handlers to be invoked during the encoding + * of this element. This occurs before any child LayoutElements are + * invoked and only if child Elements are to be invoked.

    + */ + public static final String ENCODE = "encode"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutFacet.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutFacet.java new file mode 100644 index 0000000..855bfb4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutFacet.java @@ -0,0 +1,110 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + + +/** + *

    This class defines the descriptor for LayoutFacet. A LayoutFacet + * descriptor provides information needed to attempt to obtain a Facet + * from the UIComponent. If the Facet doesn't exist, it also has the + * opportunity to provide a "default" in place of the facet.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutFacet extends LayoutElementBase implements LayoutElement { + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public LayoutFacet(LayoutElement parent, String id) { + super(parent, id); + } + + /** + *

    Returns whether this LayoutFacet should be rendered. When this + * component is used to specify an actual facet (i.e. specifies a + * UIComponent), it should not be rendred. When it + * defines a place holder for a facet, then it should be rendered.

    + * + *

    This property is normally set when the LayoutElement tree is + * created (i.e. XMLLayoutDefinitionReader). One way to + * know what to do is to see if the is LayoutFacet is + * used inside a LayoutComponent or not. If it is, it + * can be assumed that it represents an actual facet, not a place + * holder.

    + * + * @return true if {@link #encodeThis(FacesContext, UIComponent)} should + * execute + */ + public boolean isRendered() { + return _rendered; + } + + /** + * + */ + public void setRendered(boolean render) { + _rendered = render; + } + + /** + *

    This method looks for the facet on the component. If found, it + * renders it and returns false (so children will not be rendered). If + * not found, it returns true so that children will be rendered. + * Children of a LayoutFacet represent the default value for the + * Facet.

    + * + * @param context The FacesContext. + * @param component The parent UIComponent. + * + * @return true if children are to be rendered, false otherwise. + */ + protected boolean encodeThis(FacesContext context, UIComponent component) throws IOException { + // Make sure we are supposed to render facets + if (!isRendered()) { + return false; + } + + // Look for Facet + component = (UIComponent) component.getFacets(). + get(getId(context, component)); + if (component != null) { + // Found Facet, Display UIComponent + encodeChild(context, component); + + // Return false so the default won't be rendered + return false; + } + + // Return true so that the default will be rendered + return true; + } + + private boolean _rendered = true; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutForEach.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutForEach.java new file mode 100644 index 0000000..8829d8a --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutForEach.java @@ -0,0 +1,225 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.event.AfterLoopEvent; +import com.sun.jsftemplating.layout.event.BeforeLoopEvent; + + +/** + *

    This class defines a LayoutForEach {@link LayoutElement}. The + * LayoutForEach provides the functionality necessary to iteratively + * display a portion of the layout tree. The list property contains + * the List of items to iterate over.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutForEach extends LayoutComponent { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param parent The parent {@link LayoutElement} + * @param listBinding The List to iterate over + * @param key The ServletRequest attribute key + * used to store the object being processed + */ + public LayoutForEach(LayoutElement parent, String listBinding, String key) { + super(parent, null, + LayoutDefinitionManager.getGlobalComponentType(null, "foreach")); + if ((listBinding == null) || listBinding.equals("")) { + throw new IllegalArgumentException("'listBinding' is required!"); + } + if ((key == null) || key.equals("")) { + throw new IllegalArgumentException("'key' is required!"); + } + addOption("list", listBinding); + addOption("key", key); + if (listBinding.equals("$property{list}")) { + _doubleEval = true; + } + } + + + /** + *

    This method always returns true. The condition is based on an + * Iterator.hasNext() call instead of here because + * the {@link #encode(FacesContext, UIComponent)} method + * evaluates this and then calls the super. Performing the check + * here would cause the condition to be evaluated twice.

    + * + * @param context The FacesContext. + * @param component The UIComponent. + * + * @return true + */ + public boolean encodeThis(FacesContext context, UIComponent component) { + return true; + } + + /** + *

    This method evaluates the list binding for this + * LayoutForEach. This is expected to evaulate to a + * List object. If it doesn't, this method will throw a + * NullPointerException (if it evaulates to + * null), or an IllegalArgumentException if + * it doesn't evaluate to a List.

    + * + * @param context The FacesContext + * + * return The List of objects to iterate over + */ + protected List getList(FacesContext context, UIComponent comp) { + Object value = resolveValue( + context, comp, getOption("list")); + if (_doubleEval) { +// FIXME: Generalize double evaluation... all $property{} calls from inside a component?? + value = resolveValue(context, comp, value); + } + + // Make sure we found something... + if (value == null) { + throw new NullPointerException("List not found via expression: '" + + getOption("list") + "'."); + } + + // Make sure we have a List... + if (!(value instanceof List)) { + throw new IllegalArgumentException("Expression '" + + getOption("list") + + "' did not resolve to a List! Found: '" + + value.getClass().getName() + "'"); + } + + // Return the List + return (List) value; + } + + /** + *

    This method sets the Object that is currently being + * processed by this LayoutForEach. This implementation + * stores this value in the request attribute map undert the key + * provided to this LayoutForEach.

    + * + *

    As an added convenience, this method will also set an attribute + * that contains the current index number. The attribute key will be + * the same key the Object is stored under plus "-index". + * The index is stored as a String.

    + * + * @param context The FacesContext + * @param value The Object to store + * @param index The current index number of the Object + */ + private void setCurrentForEachValue(FacesContext context, Object value, int index, String key) { + Map map = context.getExternalContext().getRequestMap(); + map.put(key, value); + map.put(key + "-index", "" + index); + } + + /** + *

    This implementation overrides the parent encode + * method. It does this to cause the encode process to loop as long + * as there are more List entries to process.

    + * + * @param context The FacesContext + * @param component The UIComponent + */ + public void encode(FacesContext context, UIComponent component) throws IOException { + // Before events.. + dispatchHandlers(context, BEFORE_LOOP, + new BeforeLoopEvent(component)); + + String key = resolveValue( + context, component, getOption("key")).toString(); + + // Get the List + List list = getList(context, component); + + // Save the list size in case it is needed. + context.getExternalContext().getRequestMap().put( + key + "-size", list.size()); + + // Iterate over the values in the list and perform the requested + // action(s) per the body of the LayoutForEach + Iterator it = list.iterator(); + for (int index = 1; it.hasNext(); index++) { + setCurrentForEachValue(context, it.next(), index, key); + super.encode(context, component); + } + + // Invoke any "after" handlers + dispatchHandlers(context, AFTER_LOOP, + new AfterLoopEvent(component)); + } + + /** + *

    This method retrieves the Handlers for the requested type. But + * does *NOT* includes any handlers that are associated with the + * instance (i.e. the UIComponent). This is desired behavior when + * this is *not* a component. I am not sure if this is correct if + * we support a foreach() component. FIXME: think about this.

    + */ + public List getHandlers(String type, UIComponent comp) { + return super.getHandlers(type, null); + } + + /** + *

    This is the event "type" for + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * elements to be invoked after this LayoutForEach is processed + * (outside loop).

    + */ + public static final String AFTER_LOOP = "afterLoop"; + + /** + *

    This is the event "type" for + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * elements to be invoked before this LayoutForEach is processed + * (outside loop).

    + */ + public static final String BEFORE_LOOP = "beforeLoop"; + + /** + *

    This flag is set to true when the condition equals + * "$property{condition}". This is a special case where the value to + * be evaluated is not $property{condition}, but rather the value of + * this expression. This requires double evaluation to correct + * interpret the expression. For now this is a hack for this case + * only. In the future we may want to support an $eval{} or something + * more general syntax for doing this declaratively.

    + * + * See LayoutIf also. + */ + private boolean _doubleEval = false; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutIf.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutIf.java new file mode 100644 index 0000000..bb2c874 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutIf.java @@ -0,0 +1,114 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.el.PermissionChecker; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; + + +/** + *

    This class defines a LayoutIf {@link LayoutElement}. The LayoutIf + * provides the functionality necessary to conditionally display a portion + * of the layout tree. The condition is a boolean equation and may use + * "$...{...}" type expressions to substitute in values.

    + * + *

    Depending on its environment, this {@link LayoutElement} can represent + * an {@link com.sun.jsftemplating.component.If} UIComponent + * or simply exist as a {@link LayoutElement}. When its {@link #encode} + * method is called, the if functionality will act as a + * {@link LayoutElement}. When the + * {@link LayoutComponent#getChild(FacesContext, UIComponent)} method is + * called, it will create an {@link com.sun.jsftemplating.component.If} + * UIComponent.

    + * + * @see com.sun.jsftemplating.el.VariableResolver + * @see com.sun.jsftemplating.el.PermissionChecker + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutIf extends LayoutComponent { + private static final long serialVersionUID = 1L; + + /** + * Constructor. + */ + public LayoutIf(LayoutElement parent, String condition) { + this(parent, condition, + LayoutDefinitionManager.getGlobalComponentType(null, "if")); + } + + /** + *

    This constructor may be used by subclasses which wish to provide + * an alternate {@link ComponentType}. The {@link ComponentType} is + * used to instantiate an {@link com.sun.jsftemplating.component.If} + * UIComponent (or whatever the given + * {@link ComponentType} specifies). This occurs when this + * {@link LayoutElement} is nested inside a {@link LayoutComponent}. + * It must create a UIComponent in order to ensure it + * is executed because during rendering there is no other way to get + * control to perform the functionality provided by this + * {@link LayoutElement}.

    + */ + protected LayoutIf(LayoutElement parent, String condition, ComponentType type) { + super(parent, (String) null, type); + addOption("condition", condition); + if (condition.equals("$property{condition}")) { + _doubleEval = true; + } + } +// FIXME: getHandlers() may need to be overriden to prevent beforeEncode/afterEncode from being called multiple times in some cases. I may also need to explicitly invoke these Handlers in some cases (in the Component??); See LayoutForEach for example of what may need to be done... + + /** + * This method returns true if the condition of this LayoutIf is met, + * false otherwise. This provides the functionality for conditionally + * displaying a portion of the layout tree. + * + * @param ctx The FacesContext + * @param comp The UIComponent + * + * @return true if children are to be rendered, false otherwise. + */ + public boolean encodeThis(FacesContext ctx, UIComponent comp) { + PermissionChecker checker = new PermissionChecker( + this, comp, (_doubleEval) ? + ((String) getEvaluatedOption(ctx, "condition", comp)) : + ((String) getOption("condition"))); + return checker.hasPermission(); + } + + /** + *

    This flag is set to true when the condition equals + * "$property{condition}". This is a special case where the value to + * be evaluated is not $property{condition}, but rather the value of + * this expression. This requires double evaluation to correct + * interpret the expression. For now this is a hack for this case + * only. In the future we may want to support an $eval{} or something + * more general syntax for doing this declaratively.

    + * + * See LayoutForEach also. + */ + private boolean _doubleEval = false; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutInsert.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutInsert.java new file mode 100644 index 0000000..a68991d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutInsert.java @@ -0,0 +1,175 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import com.sun.jsftemplating.layout.event.EncodeEvent; + +import java.io.IOException; + +import java.util.Iterator; +import java.util.List; +import java.util.Stack; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + + +/** + *

    This class represents a ui:insert.

    + * + * @author Jason Lee + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutInsert extends LayoutElementBase { + private static final long serialVersionUID = 1L; + private String name; + + /** + * @param parent + * @param id + */ + public LayoutInsert(LayoutElement parent, String id) { + super(parent, id); + } + + /** + *

    Returns the name of the {@link LayoutDefine} to look for when + * including content for this LayoutInsert. This value + * may be null to indicate that it should use its body + * content.

    + */ + public String getName() { + return name; + } + + /** + *

    Sets the name of the {@link LayoutDefine} to look for when including + * content for this LayoutInsert. This value may be + * null to indicate that it should use its body content.

    + */ + public void setName(String name) { + this.name = name; + } + + /** + *

    This method is override to enable searching of its content via the + * name of this insert (if supplied), or the rendering of its body if + * not supplied, or not found. If this is encountered outside the + * context of a composition, it will render its body content also.

    + * + * @see LayoutElementBase#encodeThis(javax.faces.context.FacesContext, javax.faces.component.UIComponent) + */ + @Override + protected boolean encodeThis(FacesContext context, UIComponent component) throws IOException { + Stack stack = + LayoutComposition.getCompositionStack(context); + if (stack.empty()) { + // Render whatever is inside the insert + return true; + } + + // Get assoicated UIComposition + String name = getName(); + if (name == null) { + encodeChildren(context, component, stack.get(0)); + } else { + // First resolve any EL in the insertName + name = "" + resolveValue(context, component, name); + + // Search for specific LayoutDefine + LayoutElement def = LayoutInsert.findLayoutDefine( + context, component, stack, name); + if (def == null) { + // Render whatever is inside the insert + return true; + } else { + // Found ui:define, render it + encodeChildren(context, component, def); + } + } + return false; // Already rendered it + } + + /** + *

    Encode the appropriate children...

    + */ + private void encodeChildren(FacesContext context, UIComponent component, LayoutElement parentElt) throws IOException { + // Fire an encode event + dispatchHandlers(context, ENCODE, new EncodeEvent(component)); + + // Iterate over children + LayoutElement childElt = null; + Iterator it = parentElt.getChildLayoutElements().iterator(); + while (it.hasNext()) { + childElt = it.next(); + childElt.encode(context, component); + } + } + + /** + *

    This method searches the given the entire stack for a + * {@link LayoutDefine} with the given name.

    + */ + public static LayoutDefine findLayoutDefine(FacesContext context, UIComponent parent, List eltList, String name) { + Iterator stackIt = eltList.iterator(); + LayoutDefine define = null; + while (stackIt.hasNext()) { + define = findLayoutDefine(context, parent, stackIt.next(), name); + if (define != null) { + return define; + } + } + + // Not found! + return null; + } + + /** + *

    This method searches the given {@link LayoutElement} for a + * {@link LayoutDefine} with the given name.

    + */ + private static LayoutDefine findLayoutDefine(FacesContext context, UIComponent parent, LayoutElement elt, String name) { + Iterator it = elt.getChildLayoutElements().iterator(); + LayoutElement def = null; + while (it.hasNext()) { + def = it.next(); + if ((def instanceof LayoutDefine) && def. + getId(context, parent).equals(name)) { + // We found what we're looking for... + return (LayoutDefine) def; + } + } + + // We still haven't found it, search the child LayoutElements + it = elt.getChildLayoutElements().iterator(); + while (it.hasNext()) { + def = findLayoutDefine(context, parent, it.next(), name); + if (def != null) { + return (LayoutDefine) def; + } + } + + // Not found! + return null; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutMarkup.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutMarkup.java new file mode 100644 index 0000000..77d134c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutMarkup.java @@ -0,0 +1,158 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; +import java.util.ArrayList; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; + +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition; + + +/** + *

    This class defines a LayoutMarkup. A LayoutMarkup provides a means to + * start a markup tag and associate the current UIComponent with it for + * tool support. It also has the benefit of properly closing the markup + * tag for you.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutMarkup extends LayoutElementBase implements LayoutElement { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + */ + public LayoutMarkup(LayoutElement parent, String tag, String type) { + super(parent, tag); + _tag = tag; + _type = type; + + // Add "afterEncode" handler to close the tag (if there is a close tag) + if (!type.equals(TYPE_OPEN)) { + ArrayList handlers = new ArrayList(); + handlers.add(afterEncodeHandler); + setHandlers(AFTER_ENCODE, handlers); + } + } + + /** + * + */ + public String getTag() { + return _tag; + } + + /** + * + */ + public String getType() { + return _type; + } + + /** + *

    This method displays the text described by this component. If the + * text includes an EL expression, it will be evaluated. It returns + * true to render children.

    + * + * @param context The FacesContext + * @param component The UIComponent + * + * @return false + */ + protected boolean encodeThis(FacesContext context, UIComponent component) throws IOException { + if (getType().equals(TYPE_CLOSE)) { + return true; + } + + // Get the ResponseWriter + ResponseWriter writer = context.getResponseWriter(); + + // Render... + Object value = resolveValue(context, component, getTag()); + if (value != null) { + writer.startElement(value.toString(), component); + } + + // Always render children + return true; + } + + /** + *

    This handler takes care of closing the tag.

    + * + * @param context The HandlerContext. + */ + public static void afterEncodeHandler(HandlerContext context) throws IOException { + FacesContext ctx = context.getFacesContext(); + ResponseWriter writer = ctx.getResponseWriter(); + LayoutMarkup markup = (LayoutMarkup) context.getLayoutElement(); + Object value = ComponentUtil.getInstance(ctx).resolveValue(ctx, + markup, (UIComponent) context.getEventObject().getSource(), + markup.getTag()); + if (value != null) { + writer.endElement(value.toString()); + } + } + + /** + * + */ + public static final HandlerDefinition afterEncodeHandlerDef = + new HandlerDefinition("_markupAfterEncode"); + + /** + * + */ + public static final Handler afterEncodeHandler = + new Handler(afterEncodeHandlerDef); + + static { + afterEncodeHandlerDef.setHandlerMethod( + LayoutMarkup.class.getName(), "afterEncodeHandler"); + } + + /** + *

    This markup type writes out both the opening and closing tags.

    + */ + public static final String TYPE_BOTH = "both"; + + /** + *

    This markup type writes out the closing tag.

    + */ + public static final String TYPE_CLOSE = "close"; + + /** + *

    This markup type writes out the opening tag.

    + */ + public static final String TYPE_OPEN = "open"; + + private String _tag = null; + private String _type = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutStaticText.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutStaticText.java new file mode 100644 index 0000000..9512df0 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutStaticText.java @@ -0,0 +1,104 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import javax.el.ValueExpression; + +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; + + +/** + *

    This class defines a LayoutStaticText. A LayoutStaticText describes a + * text to be output to the screen. This element is NOT a + * UIComponent.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutStaticText extends LayoutComponent { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + */ + public LayoutStaticText(LayoutElement parent, String id, String value) { + super(parent, id, + LayoutDefinitionManager.getGlobalComponentType(null, "staticText")); + addOption("value", value); + _value = value; + } + + /** + * + */ + public String getValue() { + return _value; + } + + /** + *

    This method displays the text described by this component. If the + * text includes an EL expression, it will be evaluated. It returns + * false to avoid attempting to render children.

    + * + * @param context The FacesContext + * @param component The UIComponent + * + * @return false + */ + public boolean encodeThis(FacesContext context, UIComponent component) throws IOException { + // Get the ResponseWriter + ResponseWriter writer = context.getResponseWriter(); + + // Render the child UIComponent +// if (staticText.isEscape()) { +// writer.writeText(getValue(), "value"); +// } else { + // This code depends on the side-effect of Util.setOption + // converting the string to a ValueExpression if needed. The + // "__value" is arbitrary. + Object value = ComponentUtil.getInstance(context).setOption( + context, "__value", getValue(), + getLayoutDefinition(), component); + + // JSF 1.2 VB: + if (value instanceof ValueExpression) { + value = + ((ValueExpression) value).getValue(context.getELContext()); + } + + if (value != null) { + writer.write(value.toString()); + } +// } + + // No children + return false; + } + + private String _value = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutWhile.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutWhile.java new file mode 100644 index 0000000..bc6cd69 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/LayoutWhile.java @@ -0,0 +1,127 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import java.io.IOException; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.el.PermissionChecker; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.event.AfterLoopEvent; +import com.sun.jsftemplating.layout.event.BeforeLoopEvent; + + +/** + *

    This class defines a LayoutWhile {@link LayoutElement}. The + * LayoutWhile provides the functionality necessary to iteratively + * display a portion of the layout tree. The condition is a boolean + * equation and may use "$...{...}" type expressions to substitute + * values.

    + * + * @see com.sun.jsftemplating.el.VariableResolver + * @see com.sun.jsftemplating.el.PermissionChecker + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class LayoutWhile extends LayoutIf { + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public LayoutWhile(LayoutElement parent, String condition) { + super(parent, condition, + LayoutDefinitionManager.getGlobalComponentType(null, "while")); + } + + + /** + *

    This method always returns true. The condition is checked in + * {@link #shouldContinue(UIComponent)} instead of here because + * the {@link #encode(FacesContext, UIComponent)} method + * evaluates the condition and calls the super. Performing the check + * here would cause the condition to be evaluated twice.

    + * + * @param context The FacesContext + * @param component The UIComponent + * + * @return true + */ + public boolean encodeThis(FacesContext context, UIComponent component) { + return true; + } + + /** + *

    This method returns true if the condition of this LayoutWhile is + * met, false otherwise. This provides the functionality for + * iteratively displaying a portion of the layout tree.

    + * + * @param component The UIComponent + * + * @return true if children are to be rendered, false otherwise. + */ + protected boolean shouldContinue(UIComponent component) { + PermissionChecker checker = + new PermissionChecker(this, component, + (String) getOption("condition")); + return checker.hasPermission(); + } + + /** + *

    This implementation overrides the parent encode + * method. It does this to cause the encode process to loop while + * {@link #shouldContinue(UIComponent)} returns + * true. Currently there is no infinite loop checking, so be + * careful.

    + * + * @param context The FacesContext + * @param component The UIComponent + */ + public void encode(FacesContext context, UIComponent component) throws IOException { + dispatchHandlers(context, BEFORE_LOOP, + new BeforeLoopEvent((UIComponent) component)); + while (shouldContinue(component)) { + super.encode(context, component); + } + dispatchHandlers(context, AFTER_LOOP, + new AfterLoopEvent((UIComponent) component)); + } + + /** + *

    This is the event "type" for + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * elements to be invoked after this LayoutWhile is processed + * (outside loop).

    + */ + public static final String AFTER_LOOP = "afterLoop"; + + /** + *

    This is the event "type" for + * {@link com.sun.jsftemplating.layout.descriptors.handler.Handler} + * elements to be invoked before this LayoutWhile is processed + * (outside loop).

    + */ + public static final String BEFORE_LOOP = "beforeLoop"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/Resource.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/Resource.java new file mode 100644 index 0000000..6278b07 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/Resource.java @@ -0,0 +1,129 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors; + +import com.sun.jsftemplating.resource.ResourceFactory; +import com.sun.jsftemplating.util.Util; + + +/** + *

    This class holds information that describes a Resource. It + * provides access to a {@link ResourceFactory} for obtaining the + * actual Resource object described by this descriptor. See the + * layout.dtd file for more information on how to define a Resource + * via XML. The LayoutDefinition will add all defined Resources to + * the request scope for easy access (including via JSF EL).

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class Resource implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + /** + *

    This is the id for the Resource.

    + */ + private String _id = null; + + /** + *

    This holds "extraInfo" for the Resource, such as a ResourceBundle + * baseName.

    + */ + private String _extraInfo = null; + + + /** + *

    This is a String className for the Factory.

    + */ + private String _factoryClass = null; + + + /** + *

    The Factory that produces the desired UIComponent.

    + */ + private transient ResourceFactory _factory = null; + + + /** + *

    Constructor.

    + */ + public Resource(String id, String extraInfo, String factoryClass) { + if (id == null) { + throw new NullPointerException("'id' cannot be null!"); + } + if (factoryClass == null) { + throw new NullPointerException("'factoryClass' cannot be null!"); + } + _id = id; + _extraInfo = extraInfo; + _factoryClass = factoryClass; + _factory = createFactory(); + } + + + /** + *

    Accessor method for ID. This is the key the resource will be stored + * under in the Request scope.

    + */ + public String getId() { + return _id; + } + + /** + *

    This holds "extraInfo" for the Resource, such as a + * ResourceBundle baseName.

    + */ + public String getExtraInfo() { + return _extraInfo; + } + + + /** + *

    This method provides access to the {@link ResourceFactory}.

    + * + * @return The {@link ResourceFactory}. + */ + public ResourceFactory getFactory() { + if (_factory == null) { + _factory = createFactory(); + } + return _factory; + } + + /** + *

    This method creates a new {@link ResourceFactory}.

    + * + * @return The new {@link ResourceFactory}. + */ + protected ResourceFactory createFactory() { + try { + Class cls = Util.loadClass(_factoryClass, _factoryClass); + return (ResourceFactory) cls.newInstance(); + } catch (ClassNotFoundException ex) { + throw new RuntimeException(ex); + } catch (InstantiationException ex) { + throw new RuntimeException(ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/ApplicationAttributeOutputType.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/ApplicationAttributeOutputType.java new file mode 100644 index 0000000..774f654 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/ApplicationAttributeOutputType.java @@ -0,0 +1,93 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + + +/** + *

    This class implements the OutputType interface to provide a way to + * get/set Output values from the Application Attribute Map.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ApplicationAttributeOutputType implements OutputType { + + /** + *

    This method is responsible for retrieving the value of the Output + * from a Application attribute. 'key' may be null, if this occurs, a + * default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when retrieving the + * value from the Application attribute Map. + * + * @return The requested value. + */ + public Object getValue(HandlerContext context, IODescriptor outDesc, String key) { + if (key == null) { + // Provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get it from the Application attribute map + return context.getFacesContext().getExternalContext(). + getApplicationMap().get(key); + } + + /** + *

    This method is responsible for setting the value of the Output to + * a Application attribute. 'key' may be null, in this case, a + * default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when setting the + * value into the Application attribute Map + * + * @param value The value to set + */ + public void setValue(HandlerContext context, IODescriptor outDesc, String key, Object value) { + if (key == null) { + // Provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get it from the Application attribute map + context.getFacesContext().getExternalContext(). + getApplicationMap().put(key, value); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/ELOutputType.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/ELOutputType.java new file mode 100644 index 0000000..46c4d15 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/ELOutputType.java @@ -0,0 +1,130 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import com.sun.jsftemplating.component.ComponentUtil; + +import javax.el.ELContext; +import javax.el.ELException; +import javax.el.ValueExpression; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + + +/** + *

    This class implements the OutputType interface to provide a way to + * get/set Output values via standard EL.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ELOutputType implements OutputType { + + /** + *

    This method is responsible for retrieving the value of the output + * from EL. The "key" is expected to be the EL expression, including + * the opening and closing delimiters: #{some.el}

    + * + * @param context The HandlerContext. + * + * @param outDesc The {@link IODescriptor} for this output in which + * we are obtaining a value (not used). + * + * @param key The EL expression to evaluate. + * + * @return The requested value. + */ + public Object getValue(HandlerContext context, IODescriptor outDesc, String key) { + if (key == null) { + throw new IllegalArgumentException( + "ELOutputType's key may not be null!"); + } + + // Make sure it is an EL expression... + if (!key.startsWith("#{")) { + // If the key is not an EL expression, make it one... while this + // may cover some user-errors, I think it adds a nice ease-of-use + // feature that people may like... + key = "#{requestScope['" + key + "']}"; + } + + // See if we can find the UIComp... + UIComponent uicomp = null; + Object eventObj = context.getEventObject(); + if (eventObj instanceof UIComponent) { + uicomp = (UIComponent) eventObj; + } + + // Get it from the EL expression + FacesContext ctx = context.getFacesContext(); + return ComponentUtil.getInstance(ctx).resolveValue( + ctx, context.getLayoutElement(), uicomp, key); + } + + /** + *

    This method is responsible for setting the value of the output via + * EL. The "key" is expected to be the EL expression, including + * the opening and closing delimiters: #{some.el}

    + * + * @param context The HandlerContext. + * + * @param outDesc The IODescriptor for this Output value in which to + * obtain the value. Used to pull EL expression from + * the Handler. + * + * @param key The EL expression to evaluate. + * + * @param value The value to set. + */ + public void setValue(HandlerContext context, IODescriptor outDesc, String key, Object value) { + // It should never be null... + if (key == null) { + throw new IllegalArgumentException( + "ELOutputType's key may not be null!"); + } + + // Make sure it is an EL expression... + if (!key.startsWith("#{")) { + // If the key is not an EL expression, make it one... while this + // may cover some user-errors, I think it adds a nice ease-of-use + // feature that people may like... + key = "#{requestScope['" + key + "']}"; + } + + // Set it in EL + FacesContext facesContext = context.getFacesContext(); + ELContext elctx = facesContext.getELContext(); + ValueExpression ve = + facesContext.getApplication().getExpressionFactory(). + createValueExpression(elctx, key, Object.class); + try { + ve.setValue(elctx, value); + } catch (ELException ex) { + throw new RuntimeException( + "Unable to set handler output value named \"" + + outDesc.getName() + "\" mapped to EL expression \"" + + key + "\" on the \"" + + context.getLayoutElement().getUnevaluatedId() + + "\" element.", ex); + } + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/Handler.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/Handler.java new file mode 100644 index 0000000..9c3346e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/Handler.java @@ -0,0 +1,521 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.EventObject; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.component.ComponentUtil; +import com.sun.jsftemplating.el.PermissionChecker; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.event.UIComponentHolder; +import com.sun.jsftemplating.util.LogUtil; +import com.sun.jsftemplating.util.TypeConverter; + + +/** + *

    This class contains the information necessary to invoke a Handler. The + * {@link HandlerDefinition} class provides a definition of how to invoke + * a Handler, this class uses that information with in conjuction with + * information provided in this class to execute the handler + * method. This class typically will hold input values and + * specify where output should be stored.

    + * + *

    The handler method to be invoked must have the + * following method signature:

    + * + *

    + * + * public void doSomething(HandlerContext handlerCtx) + * + *

    + * + *

    void be replaced with any type. Depending on the type of + * event, return values may be handled differently.

    + * + *

    It is advisable to use Java annotations when defining a handler + * method. See examples of annotations in the + * com.sun.jsftemplating.handlers package. Here is an + * example:

    + * + *

    + * + * @Handler(id="abc:doSomething",
    + * input={
    + * @HandlerInput(name="foo", type=Integer.class),
    + * @HandlerInput(name="bar", type=My.class, required=true)
    + * },
    + * output={
    + * @HandlerOutput(name="result", type=String.class)
    + * })
    + * public void doSomething(HandlerContext handlerCtx) + *
    + *

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class Handler implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + */ + public Handler(HandlerDefinition handlerDef) { + setHandlerDefinition(handlerDef); + } + + /** + *

    Accessor for the {@link HandlerDefinition}.

    + */ + public HandlerDefinition getHandlerDefinition() { + return _handlerDef; + } + + /** + *

    This method sets the HandlerDefinition used by this Handler.

    + */ + protected void setHandlerDefinition(HandlerDefinition handler) { + _handlerDef = handler; + } + + /** + *

    This method is invoked by a parser to help populate this + * Handler. This information is generally static but + * may contain expressions to make the value dynamic.

    + */ + public void setInputValue(String name, Object value) { + IODescriptor inDesc = getHandlerDefinition().getInputDef(name); + if (inDesc == null) { + throw new RuntimeException("Attempted to set input value '" + + name + "' with value '" + value + "', however, '" + name + + "' is not a declared input parameter in HandlerDefinition '" + + getHandlerDefinition().getId() + "'!"); + } + _inputs.put(name, value); + } + + /** + *

    This method returns a Map of NVPs representing the input to this + * handler.

    + */ + protected Map getInputMap() { + return _inputs; + } + + /** + *

    This method simply returns the named input value, null if not + * found. It will not attempt to resolve $...{...} expressions or + * do modifications of any kind. If you are looking for a method to + * do these types of operations, try + * {@link #getInputValue(HandlerContext, String)}.

    + * + * @param name The name used to identify the input value. + */ + public Object getInputValue(String name) { + return _inputs.get(name); + } + + /** + *

    This method returns the value for the named input. Input values + * are not stored in this HandlerContext itself, but in the Handler. + * If you are trying to set input values for a handler, you must + * create a new Handler object and set its input values.

    + * + *

    This method attempts to resolve $...{...} expressions. It also + * will return the default value if the value is null. If you don't + * want these things to happen, look at + * Handler.getInputValue(String).

    + * + * @param name The input name + * + * @return The value of the input (null if not found) + */ + public Object getInputValue(HandlerContext ctx, String name) { + // Make sure the requested name is valid + IODescriptor inDesc = getHandlerDefinition().getInputDef(name); + FacesContext facesCtx = ctx.getFacesContext(); + if (inDesc == null) { + throw new RuntimeException("Attempted to get input value '" + + name + "', however, this is not a declared input " + + "parameter in handler definition '" + + getHandlerDefinition().getId() + "'! Check your handler " + + " and/or the XML (near LayoutElement '" + + ctx.getLayoutElement().getId(facesCtx, null) + + "')"); + } + + // Get the value, and parse it + Object value = getInputValue(name); + if (value == null) { + if (inDesc.isRequired()) { + throw new RuntimeException("'" + name + + "' is required for handler '" + + getHandlerDefinition().getId() + "'!"); + } + value = inDesc.getDefault(); + } + + // Resolve any expressions + EventObject event = ctx.getEventObject(); + UIComponent component = null; + if (event instanceof UIComponentHolder) { + component = ((UIComponentHolder) event).getUIComponent(); + } else if (event != null) { + Object src = event.getSource(); + if (src instanceof UIComponent) { + component = (UIComponent) src; + } + } + value = ComponentUtil.getInstance(facesCtx).resolveValue( + facesCtx, ctx.getLayoutElement(), component, value); + + // Make sure the value is the correct type... + value = TypeConverter.asType(inDesc.getType(), value); + + return value; + } + + /** + *

    This method retrieves an output value. Output values are stored + * in the location specified by the {@link OutputType} in the + * Handler.

    + * + * @param context The HandlerContext + * @param name The output name + * + * @return The value of the output (null if not set) + */ + public Object getOutputValue(HandlerContext context, String name) { + // Make sure the requested name is valid + HandlerDefinition handlerDef = getHandlerDefinition(); + IODescriptor outIODesc = handlerDef.getOutputDef(name); + if (outIODesc == null) { + throw new RuntimeException("Attempted to get output value '" + + name + "' from handler '" + handlerDef.getId() + + "', however, this is not a declared output parameter! " + + "Check your handler and/or the XML."); + } + + // Get the OutputMapping that describes how to store this output + OutputMapping outputDesc = getOutputValue(name); + + // NOTE: Interesting that this method does not evaluate the EL in + // NOTE: getOutputKey... probably a bug. Although it is very uncommon + // NOTE: (to get a output types output key which is dynamic from a + // NOTE: handler which just set the output value). It is uncommon to + // NOTE: use this method at all, let alone for dynamicly key'd + // NOTE: OutputTypes, so this code path probably hasn't ever been + // NOTE: executed. + // Return the value + return outputDesc.getOutputType(). + getValue(context, outIODesc, outputDesc.getOutputKey()); + } + + /** + *

    This method stores an output value. Output values are stored + * as specified by the {@link OutputType} in the Handler. This + * method is not used to create the "mapping" of an output value, + * for that see {@link #setOutputMapping(String, String, String)}.

    + * + * @param context The HandlerContext + * @param name The name the Handler uses for the output + * @param value The value to set + */ + public void setOutputValue(HandlerContext context, String name, Object value) { + // Make sure the requested name is valid + HandlerDefinition handlerDef = getHandlerDefinition(); + IODescriptor outIODesc = handlerDef.getOutputDef(name); + if (outIODesc == null) { + throw new RuntimeException("Attempted to set output value '" + + name + "' from handler '" + handlerDef.getId() + + "', however, this is not a declared output parameter! " + + "Check your handler and/or the XML."); + } + + // Get the OutputMapping that describes how to store this output + OutputMapping outputMapping = getOutputValue(name); + if (outputMapping == null) { + // They did not Map the output, do nothing... + return; + } + + // Make sure the value is the correct type... + value = TypeConverter.asType(outIODesc.getType(), value); + + // Set the value + EventObject event = context.getEventObject(); + UIComponent component = null; + if (event instanceof UIComponentHolder) { + component = ((UIComponentHolder) event).getUIComponent(); + } + + // Most output types appreciate resolving EL for the "key", however + // in some cases (such as the EL output type), resolving the key + // is counterproductive. Check output type to see if the output + // key should be resolved. + OutputType outType = outputMapping.getOutputType(); + String outputKey = outputMapping.getOutputKey(); +// FIXME: For now I'm going to do instanceof instead of modifying the +// FIXME: OutputType interface. I can't think of another OutputType that would +// FIXME: want this... if anyone ever has a use case, I'll happily modify the +// FIXME: OutputType interface, or add a new interface to flag this code-path. + if (!(outType instanceof ELOutputType)) { + FacesContext ctx = context.getFacesContext(); + outputKey = "" + ComponentUtil.getInstance(ctx).resolveValue( + ctx, context.getLayoutElement(), component, outputKey); + } + outType.setValue(context, outIODesc, outputKey, value); + } + + /** + *

    This method adds a new OutputMapping to this handler. An + * OutputMapping allows the handler to return a value and have it + * "mapped" to the location of your choice. The "outputType" + * corresponds to a registered {@link OutputType} + * (see {@link OutputTypeManager}).

    + * + * @param outputName The Handler's name for the output value + * @param targetKey The 'key' the OutputType uses to store the output + * @param targetType The OutputType implementation map the output + */ + public void setOutputMapping(String outputName, String targetKey, String targetType) { + // Ensure we have a valid outputName (check HandlerDefinition) + if (getHandlerDefinition().getOutputDef(outputName) == null) { + throw new IllegalArgumentException("Handler named '" + + getHandlerDefinition().getId() + "' does not declare output " + + "mapping named '" + outputName + "'."); + } + + // Ensure the data is trim + if (targetKey != null) { + targetKey = targetKey.trim(); + if (targetKey.length() == 0) { + targetKey = null; + } + } + targetType = targetType.trim(); + + try { + _outputs.put(outputName, new OutputMapping( + outputName, targetKey, targetType)); + } catch (IllegalArgumentException ex) { + throw new RuntimeException( + "Unable to create OutputMapping with given information: " + + "outputName='" + outputName + + "', targetKey='" + targetKey + + "', targetType=" + targetType + "'", ex); + } + } + + /** + *

    This method returns the {@link OutputMapping} for the given + * name. If not found, it will return + * null.

    + */ + public OutputMapping getOutputValue(String name) { + return _outputs.get(name); + } + + /** + *

    This method returns the condition that must be true in order for + * this Handler (or its child Handlers) to + * be invoked. If this condition is empty ("") or null, + * it is considered to be true.

    + */ + public String getCondition() { + return _condition; + } + + /** + *

    This method sets the condition that must evaluate to true in order + * for this Handler to be invoked.

    + */ + public void setCondition(String cond) { + if (cond != null) { + cond = cond.trim(); + } + _condition = cond; + } + + /** + *

    This method determines if the handler is static.

    + */ + public boolean isStatic() { + return getHandlerDefinition().isStatic(); + } + + /** + *

    This method adds a Handler to the list of child + * Handlers. Child Handlers are executed + * AFTER this Handler is executed.

    + * + * @param desc The Handler to add. + */ + public void addChildHandler(Handler desc) { + if (_childHandlers == _emptyList) { + _childHandlers = new ArrayList(); + } + _childHandlers.add(desc); + } + + /** + *

    This method sets the List of child + * Handlers.

    + * + * @param childHandlers The List of child + * Handlers. + */ + public void setChildHandlers(List childHandlers) { + if ((childHandlers == null) || (childHandlers.size() == 0)) { + childHandlers = _emptyList; + } + _childHandlers = childHandlers; + } + + /** + *

    This method retrieves the List of child + * {@link Handler}s. This List should not be changed + * directly. Call {@link #addChildHandler(Handler)}, or make a copy + * and call {@link #setChildHandlers(List)}.

    + * + * @return The List of child {@link Handler}s. + */ + public List getChildHandlers() { + return _childHandlers; + } + + /** + *

    This method is responsible for invoking this Handler + * as well as all child Handlers. Neither will be + * invoked if this methods condition is non-null and unstatisfied + * (see {@link #getCondition()}). The method associated with this + * Handler will be invoked first, then any child + * Handlers.

    + * + * @param handlerContext The {@link HandlerContext}. + */ + public Object invoke(HandlerContext handlerContext) throws InstantiationException, IllegalAccessException, InvocationTargetException { + Object result = null; + HandlerDefinition handlerDef = getHandlerDefinition(); + + // Invoke + if (hasPermission(handlerContext)) { + // Only attempt to do this if there is a handler method, there + // might only be child handlers + Method method = handlerDef.getHandlerMethod(); + if (method != null) { + Object instance = null; + if (!isStatic()) { + // Get the class that contains the method + instance = method.getDeclaringClass().newInstance(); + } + + // Invoke the Method + result = method.invoke(instance, new Object[] {handlerContext}); + } + + // Execute all the child handlers + if ((result == null) || (!result.toString().equals("false"))) { + // NOTE: 'handler' in handlerContext will change. + // before we execute this Handler. + // FIRST: Execute handlerDef child handlers + List handlers = handlerDef.getChildHandlers(); + Object retVal = null; + LayoutElement elt = handlerContext.getLayoutElement(); + if (handlers.size() > 0) { + retVal = elt.dispatchHandlers(handlerContext, handlers); + if (retVal != null) { + result = retVal; + } + } + + // NEXT: Execute instance child handlers + // Useful for applying a condition to a group + handlers = getChildHandlers(); + if (handlers.size() > 0) { + retVal = elt.dispatchHandlers(handlerContext, handlers); + if (retVal != null) { + result = retVal; + } + } + } + } else { + if (LogUtil.finerEnabled()) { + LogUtil.finer("Handler '" + handlerDef.getId() + + "' skipped because condition not met: '" + + getCondition() + "'."); + } + } + + // Return the result (null if no result) + return result; + } + + /** + *

    This method determines if the condition + * (see {@link #getCondition()}) is satisfied.

    + * + * @return true if the condition is met. + */ + public boolean hasPermission(HandlerContext handlerContext) { + String cond = getCondition(); + if ((cond == null) || cond.equals("")) { + return true; + } + + // Try to get the UIComponent + UIComponent comp = null; + Object obj = handlerContext.getEventObject().getSource(); + if (obj instanceof UIComponent) { + comp = (UIComponent) obj; + } + + // Create a PermissionChecker + PermissionChecker checker = new PermissionChecker( + handlerContext.getLayoutElement(), comp, cond); + + // Return the result + return checker.hasPermission(); + } + + + private HandlerDefinition _handlerDef = null; + + private String _condition = null; + + private List _childHandlers = _emptyList; + + private Map _inputs = new HashMap(); + private Map _outputs = + new HashMap(); + + private static final List _emptyList = new ArrayList(0); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerContext.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerContext.java new file mode 100644 index 0000000..b345737 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerContext.java @@ -0,0 +1,125 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import java.util.EventObject; + +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface HandlerContext { + + /** + *

    Accessor for the FacesContext.

    + * + * @return FacesContext + */ + public FacesContext getFacesContext(); + + /** + *

    Accessor for the LayoutElement associated with this Handler. The + * LayoutElement associated with this Handler is the LayoutElement + * which declared the handler. This provides a way for the handler + * to obtain access to the LayoutElement which is responsible for it + * being invoked.

    + */ + public LayoutElement getLayoutElement(); + + /** + *

    Accessor for the EventObject associated with this Handler. This + * may be null if an EventObject was not created for this handler. + * An EventObject, if it does exist, may provide additional details + * describing the context in which this Event is invoked.

    + */ + public EventObject getEventObject(); + + /** + *

    This method provides access to the EventType. This is mostly + * helpful for diagnostics, but may be used in a handler to determine + * more information about the context in which the code is + * executing.

    + */ + public String getEventType(); + + /** + *

    Accessor for the Handler descriptor for this Handler. The Handler + * descriptor object contains specific meta information describing + * the invocation of this handler. This includes details such as + * input values, and where output values are to be set.

    + */ + public Handler getHandler(); + + /** + *

    Setter for the Handler descriptor for this Handler.

    + * + * @param handler The Handler + */ + public void setHandler(Handler handler); + + /** + *

    Accessor for the Handler descriptor for this Handler. The + * HandlerDefinition descriptor contains meta information about the + * actual Java handler that will handle the processing. This + * includes the inputs required, outputs produces, and the types for + * both.

    + */ + public HandlerDefinition getHandlerDefinition(); + + /** + *

    This method returns the value for the named input. Input values + * are not stored in this Context itself, but in the Handler. If + * you are trying to set input values for a handler, you must create + * a new Handler object and set its input values.

    + * + * @param name The input name + * + * @return The value of the input (null if not found) + */ + public Object getInputValue(String name); + + /** + *

    This method retrieves an Output value. Output values must not be + * stored in this Context itself (remember HandlerContext objects + * are shared). Output values are stored according to what is + * specified in the HandlerDefintion.

    + * + * @param name The output name + * + * @return The value of the output (null if not found) + */ + public Object getOutputValue(String name); + + /** + *

    This method sets an Output value. Output values must not be + * stored in this Context itself (remember HandlerContext objects + * are shared). Output values are stored according to what is + * specified in the HandlerDefintion.

    + */ + public void setOutputValue(String name, Object value); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerContextImpl.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerContextImpl.java new file mode 100644 index 0000000..a2495a6 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerContextImpl.java @@ -0,0 +1,174 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import java.util.EventObject; + +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class HandlerContextImpl implements HandlerContext { + + /** + *

    Constructor.

    + */ + public HandlerContextImpl(FacesContext context, LayoutElement layoutDesc, EventObject event, String eventType) { + _facesContext = context; + _layoutDesc = layoutDesc; + _event = event; + _eventType = eventType; + } + + /** + *

    Constructor that gets all its values from the given + * HandlerContext.

    + * + * @param context The HandlerContext to clone. + */ + public HandlerContextImpl(HandlerContext context) { + _facesContext = context.getFacesContext(); + _layoutDesc = context.getLayoutElement(); + _event = context.getEventObject(); + _eventType = context.getEventType(); + _handler = context.getHandler(); + } + + /** + *

    Accessor for the FacesContext.

    + * + * @return FacesContext + */ + public FacesContext getFacesContext() { + return _facesContext; + } + + /** + *

    Accessor for the LayoutElement associated with this Handler.

    + */ + public LayoutElement getLayoutElement() { + return _layoutDesc; + } + + /** + *

    Accessor for the EventObject associated with this Handler. This + * may be null if an EventObject was not created for this handler. + * An EventObject, if it does exist, may provide additional details + * describing the context in which this Event is invoked.

    + */ + public EventObject getEventObject() { + return _event; + } + + /** + *

    This method provides access to the EventType. This is mostly + * helpful for diagnostics, but may be used in a handler to determine + * more information about the context in which the code is + * executing.

    + */ + public String getEventType() { + return _eventType; + } + + /** + *

    Accessor for the Handler descriptor for this Handler. The Handler + * descriptor object contains specific meta information describing + * the invocation of this handler. This includes details such as + * input values, and where output values are to be set.

    + */ + public Handler getHandler() { + return _handler; + } + + /** + *

    Setter for the Handler descriptor for this Handler.

    + */ + public void setHandler(Handler handler) { + _handler = handler; + } + + /** + *

    Accessor for the Handler descriptor for this Handler. The + * HandlerDefinition descriptor contains meta information about the + * actual Java handler that will handle the processing. This + * includes the inputs required, outputs produces, and the types for + * both.

    + */ + public HandlerDefinition getHandlerDefinition() { + return _handler.getHandlerDefinition(); + } + + /** + *

    This method returns the value for the named input. Input values + * are not stored in this HandlerContext itself, but in the Handler. + * If you are trying to set input values for a handler, you must + * create a new Handler object and set its input values.

    + * + *

    This method attempts to resolve $...{...} expressions. It also + * will return the default value if the value is null. If you don't + * want these things to happen, look at + * Handler.getInputValue(String).

    + * + * @param name The input name + * + * @return The value of the input (null if not found) + */ + public Object getInputValue(String name) { + return getHandler().getInputValue(this, name); + } + + /** + *

    This method retrieves an Output value. Output values must not be + * stored in this Context itself (remember HandlerContext objects + * are shared). Output values are stored according to what is + * specified in the HandlerDefintion.

    + * + * @param name The output name + * + * @return The value of the output (null if not found) + */ + public Object getOutputValue(String name) { + return getHandler().getOutputValue(this, name); + } + + /** + *

    This method sets an Output value. Output values must not be + * stored in this Context itself (remember HandlerContext objects + * are shared). Output values are stored according to what is + * specified in the HandlerDefintion.

    + */ + public void setOutputValue(String name, Object value) { + getHandler().setOutputValue(this, name, value); + } + + private String _eventType = null; + private FacesContext _facesContext = null; + private LayoutElement _layoutDesc = null; + private EventObject _event = null; + private Handler _handler = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerDefinition.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerDefinition.java new file mode 100644 index 0000000..85c2939 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/HandlerDefinition.java @@ -0,0 +1,337 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import com.sun.jsftemplating.util.Util; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + *

    A HandlerDefinition defines a "handler" that may be invoked in the + * process of executing an event. A HandlerDefinition has an + * id, java method, input + * definitions, output definitions, and + * child handlers.

    + * + *

    The java method to be invoked must have the + * following method signature:

    + * + *

    + * public void beginDisplay(HandlerContext handlerCtx) + *

    + * + *

    void above can return a value. Depending on the type of + * event, return values may be handled differently.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class HandlerDefinition implements java.io.Serializable { + + /** + * Constructor + */ + public HandlerDefinition(String id) { + _id = id; + } + + /** + * This method returns the id for this handler. + */ + public String getId() { + return _id; + } + + /** + * For future tool support + */ + public String getDescription() { + return _description; + } + + /** + * For future tool support + */ + public void setDescription(String desc) { + _description = desc; + } + + /** + *

    This method sets the event handler (method) to be invoked. The + * method should be public and accept a prameter of type + * "HandlerContext" Example:

    + * + *

    + * public void beginDisplay(HandlerContext handlerCtx) + *

    + * + * @param cls The full class name containing method + * @param methodName The method name of the handler within class + */ + public void setHandlerMethod(String cls, String methodName) { + if ((cls == null) || (methodName == null)) { + throw new IllegalArgumentException( + "Class name and method name must be non-null!"); + } + _methodClass = cls; + _methodName = methodName; + } + + /** + * + */ + public void setHandlerMethod(Method method) { + if (method != null) { + _methodName = method.getName(); + _methodClass = method.getDeclaringClass().getName(); + } else { + _methodName = null; + _methodClass = null; + } + _method = method; + } + + /** + *

    This method determines if the handler is static.

    + */ + public boolean isStatic() { + if (_static == null) { + _static = Boolean.valueOf( + Modifier.isStatic(getHandlerMethod().getModifiers())); + } + return _static.booleanValue(); + } + + /** + * + */ + public Method getHandlerMethod() { + if (_method != null) { + // return cached Method + return _method; + } + + // See if we have the info to find it + if ((_methodClass != null) && (_methodName != null)) { + // Find the class + Class clzz = null; + try { + clzz = Util.loadClass(_methodClass, _methodClass); + } catch (ClassNotFoundException ex) { + throw new RuntimeException("'" + + _methodClass + "' not found for method '" + + _methodName + "'!", ex); + } + + // Find the method on the class + Method method = null; + try { + method = clzz.getMethod(_methodName, EVENT_ARGS); + } catch (NoSuchMethodException ex) { + throw new RuntimeException( + "Method '" + _methodName + "' not found!", ex); + } + + // Cache the _method + _method = method; + } + + // Return the Method if there is one + return _method; + } + + /** + * This method adds an IODescriptor to the list of input descriptors. + * These descriptors define the input parameters to this handler. + * + * @param desc The input IODescriptor to add + */ + public void addInputDef(IODescriptor desc) { + _inputDefs.put(desc.getName(), desc); + } + + /** + * This method sets the input IODescriptors for this handler. + * + * @param inputDefs The Map of IODescriptors + */ + public void setInputDefs(Map inputDefs) { + if (inputDefs == null) { + throw new IllegalArgumentException( + "inputDefs cannot be null!"); + } + _inputDefs = inputDefs; + } + + /** + * This method retrieves the Map of input IODescriptors. + * + * @return The Map of IODescriptors + */ + public Map getInputDefs() { + return _inputDefs; + } + + /** + * This method returns the requested IODescriptor, null if not found. + */ + public IODescriptor getInputDef(String name) { + return _inputDefs.get(name); + } + + /** + * This method adds an IODescriptor to the list of output descriptors. + * These descriptors define the output parameters to this handler. + * + * @param desc The IODescriptor to add + */ + public void addOutputDef(IODescriptor desc) { + _outputDefs.put(desc.getName(), desc); + } + + /** + * This method sets the output IODescriptors for this handler. + * + * @param outputDefs The Map of output IODescriptors + */ + public void setOutputDefs(Map outputDefs) { + if (outputDefs == null) { + throw new IllegalArgumentException( + "outputDefs cannot be null!"); + } + _outputDefs = outputDefs; + } + + /** + * This method retrieves the Map of output IODescriptors. + * + * @return The Map of output IODescriptors + */ + public Map getOutputDefs() { + return _outputDefs; + } + + /** + * This method returns the requested IODescriptor, null if not found. + */ + public IODescriptor getOutputDef(String name) { + return _outputDefs.get(name); + } + + /** + *

    This method adds a {@link Handler} to the list of child + * {@link Handler}s. Child {@link Handler}s are executed AFTER this + * {@link Handler} is executed.

    + * + * @param desc The {@link Handler} to add. + */ + public void addChildHandler(Handler desc) { + if (_childHandlers == _emptyList) { + _childHandlers = new ArrayList(); + } + _childHandlers.add(desc); + } + + /** + *

    This method sets the List of child {@link Handler}s + * for this HandlerDefinition. + * + * @param childHandlers The List of child + * {@link Handler}s. + */ + public void setChildHandlers(List childHandlers) { + if ((childHandlers == null) || (childHandlers.size() == 0)) { + childHandlers = _emptyList; + } + _childHandlers = childHandlers; + } + + /** + *

    This method retrieves the List of child + * {@link Handler}s. This List should not be changed + * directly. Call {@link #addChildHandler(Handler)}, or make a copy + * and call {@link #setChildHandlers(List)}.

    + * + * @return The List of child {@link Handler}s for this + * HandlerDefinition. + */ + public List getChildHandlers() { + return _childHandlers; + } + + /** + *

    This toString() provides detailed information about this + * HandlerDefinition.

    + */ + public String toString() { + // Print the basic info... + Formatter printf = new Formatter(); + printf.format("%-40s %s.%s\n", _id, _methodClass, _methodName); + + // Print the description + if (_description != null) { + printf.format("%s\n", _description); + } + + // Print the Inputs + Iterator it = _inputDefs.values().iterator(); + while (it.hasNext()) { + printf.format(" INPUT> %s\n", it.next().toString()); + } + + // Print the Outputs + it = _outputDefs.values().iterator(); + while (it.hasNext()) { + printf.format(" OUTPUT> %s\n", it.next().toString()); + } + + // Print the Child Handlers (TBD...) + + // Return the result + return printf.toString(); + } + + + public static final Class[] EVENT_ARGS = new Class[] {HandlerContext.class}; + + + private String _id = null; + private String _description = null; + private String _methodClass = null; + private String _methodName = null; + private transient Method _method = null; + private Map _inputDefs = new HashMap(5); + private Map _outputDefs = new HashMap(5); + private List _childHandlers = _emptyList; + private transient Boolean _static = null; + + private static final List _emptyList = new ArrayList(0); + private static final long serialVersionUID = 0xA8B7C6D5E4F30211L; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/IODescriptor.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/IODescriptor.java new file mode 100644 index 0000000..f8e742c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/IODescriptor.java @@ -0,0 +1,208 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import com.sun.jsftemplating.util.Util; + +import java.util.Formatter; +import java.util.HashMap; +import java.util.Map; + + +/** + *

    This class describes an input or output parameter.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class IODescriptor implements java.io.Serializable { + + /** + *

    Constructor.

    + * + * @param name The name of the input/output field. + * @param type The type of the input/output field. + */ + public IODescriptor(String name, String type) { + setName(name); + setType(type); + } + + + /** + *

    This method returns the name for this handler definition.

    + */ + public String getName() { + if (_name == null) { + throw new NullPointerException("Name cannot be null!"); + } + return _name; + } + + + /** + *

    This method sets the handler definitions name (used by the + * contsrutor).

    + */ + protected void setName(String name) { + _name = name; + } + + + /** + *

    For future tool support.

    + */ + public String getDescription() { + return _description; + } + + + /** + *

    For future tool support.

    + */ + public void setDescription(String desc) { + _description = desc; + } + + + /** + *

    This method returns the type for this parameter.

    + */ + public Class getType() { + return _type; + } + + + /** + *

    This method sets the type for this parameter.

    + */ + public void setType(Class type) { + _type = type; + } + + + /** + *

    This method sets the type for this parameter.

    + */ + public void setType(String type) { + if ((type == null) || (type.trim().length() == 0)) { + return; + } + Class cls = (Class) _typeMap.get(type); + if (cls == null) { + try { + cls = Util.loadClass(type, type); + } catch (Exception ex) { + throw new RuntimeException( + "Unable to determine parameter type '" + type + + "' for parameter named '" + getName() + "'.", ex); + } + } + _type = cls; + } + + + /** + *

    This method returns the default for this parameter (valid for input + * only).

    + */ + public Object getDefault() { + return _default; + } + + + /** + *

    This method sets the default for this parameter (valid for input + * only).

    + */ + public void setDefault(Object def) { + _default = def; + } + + /** + *

    This method inidicates if the input is required (valid for input + * only).

    + */ + public boolean isRequired() { + return _required; + } + + /** + *

    This method specifies whether this input field is required.

    + */ + public void setRequired(boolean required) { + _required = required; + } + + /** + *

    This toString() method provides detailed information + * about this IODescriptor.

    + */ + public String toString() { + // Print the info... + Formatter printf = new Formatter(); + printf.format("%-28s %-40s %s", + _name + (_required ? "(required)" : ""), + _type, + (_default == null) ? "" : ("DEFAULT: " + _default.toString())); + + // Print description if available + if (_description != null) { + printf.format("\n\t%s", _description); + } + + // Return the result... + return printf.toString(); + } + + // The following provides some basic pre-defined types + private static Map _typeMap = new HashMap(); + static { + _typeMap.put("boolean", Boolean.class); + _typeMap.put("Boolean", Boolean.class); + _typeMap.put("byte", Byte.class); + _typeMap.put("Byte", Byte.class); + _typeMap.put("char", Character.class); + _typeMap.put("Character", Character.class); + _typeMap.put("double", Double.class); + _typeMap.put("Double", Double.class); + _typeMap.put("float", Float.class); + _typeMap.put("Float", Float.class); + _typeMap.put("int", Integer.class); + _typeMap.put("Integer", Integer.class); + _typeMap.put("long", Long.class); + _typeMap.put("Long", Long.class); + _typeMap.put("short", Short.class); + _typeMap.put("Short", Short.class); + _typeMap.put("char[]", String.class); + _typeMap.put("String", String.class); + _typeMap.put("Object", Object.class); + } + + private String _name = null; + private String _description = null; + private Object _default = null; // Input only + private Class _type = Object.class; + private boolean _required = false; // Input only + + private static final long serialVersionUID = 0xA9B8C7D6E5F40312L; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputMapping.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputMapping.java new file mode 100644 index 0000000..6e4d5fb --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputMapping.java @@ -0,0 +1,117 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import javax.faces.context.FacesContext; + + +/** + *

    This class holds OutputMapping value meta information for individual + * instances of Handler Objects. This information is necessary to provide + * the location to store the output value for a specific invocation of a + * handler. This is data consists of the name the Handler uses for the + * output, the OutputType, and optionally the OutputType key to use when + * storing/retrieving the output value.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class OutputMapping implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor with targetKey as null. This constructor will + * throw an IllegalArgumentException if outputName or + * targetOutputType is null.

    + * + * @param outputName The name the Handler uses for output value + * @param targetOutputType OutputType that will store the output value + * + * @see OutputTypeManager + * + * @throws IllegalArumentException If outputName / targetOutputType is null + */ + public OutputMapping(String outputName, String targetOutputType) { + this(outputName, null, targetOutputType); + } + + + /** + *

    Constructor with all values supplied as Strings. This constructor + * will throw an IllegalArgumentException if outputName or + * targetOutputType is null.

    + * + * @param outputName The name the Handler uses for output value + * @param targetKey The key the OutputType will use + * @param targetOutputType OutputType that will store the output value + * + * @see OutputTypeManager + * + * @throws NullPointerException If outputName / targetOutputType is null + */ + public OutputMapping(String outputName, String targetKey, String targetOutputType) { + // Sanity checks... + if ((outputName == null) || (outputName.length() == 0)) { + throw new NullPointerException("'outputName' is required!"); + } + if (targetOutputType == null) { + throw new NullPointerException("'targetOutputType' is required!"); + } + _outputName = outputName; + _targetKey = targetKey; + _targetOutputType = targetOutputType; + } + + /** + * Accessor for outputName. + */ + public String getOutputName() { + return _outputName; + } + + /** + * Accessor for targetKey. + */ + public String getOutputKey() { + return _targetKey; + } + + /** + * Accessor for targetOutputType. + */ + public OutputType getOutputType() { + FacesContext ctx = FacesContext.getCurrentInstance(); + return OutputTypeManager.getManager(ctx).getOutputType(ctx, _targetOutputType); + } + + /** + *

    Accessor for targetOutputType as a String.

    + */ + public String getStringOutputType() { + return _targetOutputType; + } + + + private String _outputName = null; + private String _targetKey = null; + private String _targetOutputType = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputType.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputType.java new file mode 100644 index 0000000..d9cbb86 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputType.java @@ -0,0 +1,72 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + + +/** + *

    This interface provides an abstraction for different locations for + * storing output from a handler. Implementations may store values in + * Session, request attributes, databases, etc.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface OutputType { + + /** + *

    This method is responsible for retrieving the value of the Output + * from the destination that was specified by handler. 'key' may be + * null. In cases where it is not needed, it can be ignored. If it + * is needed, the implementation may either provide a default or + * throw an exception.

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when retrieving the + * value from the OutputType + * + * @return The requested value. + */ + public Object getValue(HandlerContext context, IODescriptor outDesc, String key); + + /** + *

    This method is responsible for setting the value of the Output + * to the destination that was specified by handler. 'key' may be + * null. In cases where it is not needed, it can be ignored. If it + * is needed, the implementation may either provide a default or + * throw an exception.

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when setting the + * value from the OutputType + * + * @param value The value to set + */ + public void setValue(HandlerContext context, IODescriptor outDesc, String key, Object value); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputTypeManager.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputTypeManager.java new file mode 100644 index 0000000..805f6b4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/OutputTypeManager.java @@ -0,0 +1,244 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import com.sun.jsftemplating.util.Util; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; + + +/** + *

    OutputTypeManager manages the various {@link OutputType}s + * that can be used. The {@link OutputType}s are managed statically.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class OutputTypeManager { + + /** + * Constructor. + */ + protected OutputTypeManager() { + } + + /** + *

    Attempts to get the FacesContext and returns the + * results from {@link #getManager(FacesContext)}.

    + */ + public static OutputTypeManager getInstance() { + return getManager(FacesContext.getCurrentInstance()); + } + + /** + *

    This is a factory method for obtaining an OutputTypeManager + * instance. This implementation uses the external context's + * initParams to look for the OutputTypeManager class. If it + * exists, the specified concrete OutputTypeManager class will + * be used. Otherwise, the default will be used -- which is an + * instance of this class. The initParam key is: + * {@link #OUTPUT_TYPE_MANAGER_KEY}.

    + * + * @param context The FacesContext + * + * @see #OUTPUT_TYPE_MANAGER_KEY + */ + public static OutputTypeManager getManager(FacesContext context) { + if (context == null) { + return _defaultInstance; + } + + // If the context is non-null, check for init parameter specifying + // the Manager + String className = null; + Map initParams = context.getExternalContext().getInitParameterMap(); + if (initParams.containsKey(OUTPUT_TYPE_MANAGER_KEY)) { + className = (String) initParams.get(OUTPUT_TYPE_MANAGER_KEY); + } + return getManager(context, className); + } + + + /** + *

    This method is a singleton factory method for obtaining an instance + * of an OutputTypeManager. It is possible that multiple + * different implementations of OutputTypeManagers will + * be used within the same application. This is fine. Someone may + * provide a different OutputTypeManager to locate + * OutputType's in a different way (XML, database, file, + * java code, etc.).

    + */ + public static OutputTypeManager getManager(FacesContext ctx, String className) { + if (className == null) { + // Default case... + return _defaultInstance; + } + OutputTypeManager ldm = null; + + // FacesContext + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Map instances = null; + if (ctx != null) { + instances = (Map) + ctx.getExternalContext().getApplicationMap().get(OTM_INSTANCES); + } + if (instances == null) { + // NO instances defined yet... + instances = new HashMap(2); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put(OTM_INSTANCES, instances); + } + } else { + // See if we've found this before... + ldm = instances.get(className); + } + if (ldm == null) { + // Not found yet, try to find it... + try { + ldm = (OutputTypeManager) Util.loadClass(className, className). + getMethod("getInstance", (Class []) null). + invoke((Object) null, (Object []) null); + } catch (ClassNotFoundException ex) { + throw new RuntimeException(ex); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } catch (InvocationTargetException ex) { + throw new RuntimeException(ex); + } catch (NullPointerException ex) { + throw new RuntimeException(ex); + } catch (ClassCastException ex) { + throw new RuntimeException(ex); + } + + // We found it + instances.put(className, ldm); + } + return ldm; + } + + /** + *

    This method retrieves a List of {@link OutputType}. + * Changes to this List have no effect.

    + * + * @return The {@link OutputType}s. + */ + public List getOutputTypes(FacesContext ctx) { + return new ArrayList(getOutputTypeMap(ctx).values()); + } + + /** + *

    Returns the application scope Map which holds all the + * {@link OutputType}s.

    + */ + private Map getOutputTypeMap(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + Map outputTypeMap = null; + if (ctx != null) { + outputTypeMap = (Map) + ctx.getExternalContext().getApplicationMap().get(OTM_TYPE_MAP); + } + if (outputTypeMap == null) { + // 1st time for this app... initialize it + outputTypeMap = new HashMap(8); + PageAttributeOutputType pageType = new PageAttributeOutputType(); + outputTypeMap.put(EL_TYPE, new ELOutputType()); + outputTypeMap.put(PAGE_ATTRIBUTE_TYPE, pageType); + outputTypeMap.put(PAGE_ATTRIBUTE_TYPE2, pageType); + outputTypeMap.put(APP_ATTRIBUTE_TYPE, + new ApplicationAttributeOutputType()); + outputTypeMap.put(REQUEST_ATTRIBUTE_TYPE, + new RequestAttributeOutputType()); + outputTypeMap.put(SESSION_ATTRIBUTE_TYPE, + new SessionAttributeOutputType()); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put( + OTM_TYPE_MAP, outputTypeMap); + } + } + + // Return the OutputType Map + return outputTypeMap; + } + + /** + *

    This method retrieves an OutputType.

    + * + * @param name The name of the OutputType. + * + * @return The requested OutputType. + */ + public OutputType getOutputType(FacesContext ctx, String name) { + return getOutputTypeMap(ctx).get(name); + } + + /** + *

    This method sets an OutputType.

    + * + * @param name The name of the OutputType. + * @param outputType The OutputType. + */ + public void setOutputType(FacesContext ctx, String name, OutputType outputType) { + // Not thread safe... + getOutputTypeMap(ctx).put(name, outputType); + } + + /** + *

    This is the default implementation of the OutputTypeManager, which + * happens to be an instance of this class (because I'm too lazy to + * do this right).

    + */ + private static final OutputTypeManager _defaultInstance = + new OutputTypeManager(); + + + /** + *

    This constant defines the layout definition manager implementation + * key for initParams. The value for this initParam should be the + * full class name of an {@link OutputTypeManager}. + * ("outputTypeManagerImpl")

    + */ + public static final String OUTPUT_TYPE_MANAGER_KEY = + "outputTypeManagerImpl"; + private static final String OTM_INSTANCES = + "__jsft_OutputTypeManagers"; + private static final String OTM_TYPE_MAP = + "__jsft_OutputType_map"; + + public static final String REQUEST_ATTRIBUTE_TYPE = "attribute"; + public static final String PAGE_ATTRIBUTE_TYPE = "page"; + public static final String PAGE_ATTRIBUTE_TYPE2 = "pageSession"; + public static final String SESSION_ATTRIBUTE_TYPE = "session"; + public static final String APP_ATTRIBUTE_TYPE = "application"; + public static final String EL_TYPE = "el"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/PageAttributeOutputType.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/PageAttributeOutputType.java new file mode 100644 index 0000000..1cc0ac3 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/PageAttributeOutputType.java @@ -0,0 +1,120 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + +import java.io.Serializable; +import java.util.Map; + +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; + +import com.sun.jsftemplating.el.PageSessionResolver; + + +/** + *

    This class implements the OutputType interface to provide a way to + * get/set Output values from the Page attribute Map (see + * {@link PageSessionResolver}).

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class PageAttributeOutputType implements OutputType { + + /** + *

    This method is responsible for retrieving the value of the Output + * from a Page Session Attribute. 'key' may be null, if this occurs, + * a default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The HandlerContext + * + * @param outDesc The {@link IODescriptor} for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when retrieving the + * value from the Page Session Attribute Map. + * + * @return The requested value, null if not found. + */ + public Object getValue(HandlerContext context, IODescriptor outDesc, String key) { + if (key == null) { + // Provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get the Page Session Map + Map map = + PageSessionResolver.getPageSession( + context.getFacesContext(), (UIViewRoot) null); + + // Get the value to return + Serializable value = null; + if (map != null) { + value = map.get(key); + } + + // Return it... + return value; + } + + /** + *

    This method is responsible for setting the value of the Output to + * a Page Session Attribute. 'key' may be null, in this case, a + * default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The {@link HandlerContext} + * + * @param outDesc The {@link IODescriptor} for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when setting the + * value into the Page Session Attribute Map + * + * @param value The value to set + */ + public void setValue(HandlerContext context, IODescriptor outDesc, String key, Object value) { + // Ensure we have a key... + if (key == null) { + // We don't, provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get the Page Session Map + FacesContext ctx = context.getFacesContext(); + Map map = + PageSessionResolver.getPageSession(ctx, (UIViewRoot) null); + if (map == null) { + map = PageSessionResolver.createPageSession(ctx, (UIViewRoot) null); + } + + // Set the Page Session Attribute Map + map.put(key, (Serializable) value); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/RequestAttributeOutputType.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/RequestAttributeOutputType.java new file mode 100644 index 0000000..38e6a0c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/RequestAttributeOutputType.java @@ -0,0 +1,93 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + + +/** + *

    This class implements the OutputType interface to provide a way to + * get/set Output values from a ServletRequest attribute Map.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class RequestAttributeOutputType implements OutputType { + + /** + *

    This method is responsible for retrieving the value of the Output + * from a Request attribute. 'key' may be null, if this occurs, a + * default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when retrieving the + * value from the ServletRequest attribute Map. + * + * @return The requested value. + */ + public Object getValue(HandlerContext context, IODescriptor outDesc, String key) { + if (key == null) { + // Provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get it from the Request attribute map + return context.getFacesContext().getExternalContext(). + getRequestMap().get(key); + } + + /** + *

    This method is responsible for setting the value of the Output to + * a ServletRequest attribute. 'key' may be null, in this case, a + * default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when setting the + * value into the ServletRequest attribute Map + * + * @param value The value to set + */ + public void setValue(HandlerContext context, IODescriptor outDesc, String key, Object value) { + if (key == null) { + // Provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get it from the Request attribute map + context.getFacesContext().getExternalContext(). + getRequestMap().put(key, value); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/SessionAttributeOutputType.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/SessionAttributeOutputType.java new file mode 100644 index 0000000..3a9f435 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/descriptors/handler/SessionAttributeOutputType.java @@ -0,0 +1,93 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.descriptors.handler; + + +/** + *

    This class implements the OutputType interface to provide a way to + * get/set Output values from the Session attribute Map.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class SessionAttributeOutputType implements OutputType { + + /** + *

    This method is responsible for retrieving the value of the Output + * from a Session attribute. 'key' may be null, if this occurs, a + * default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when retrieving the + * value from the Session attribute Map. + * + * @return The requested value. + */ + public Object getValue(HandlerContext context, IODescriptor outDesc, String key) { + if (key == null) { + // Provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get it from the Session attribute map + return context.getFacesContext().getExternalContext(). + getSessionMap().get(key); + } + + /** + *

    This method is responsible for setting the value of the Output to + * a Session attribute. 'key' may be null, in this case, a + * default name will be provided. That name will follow the + * following format:

    + * + *

    [handler-id]:[output-name]

    + * + * @param context The HandlerContext + * + * @param outDesc The IODescriptor for this Output value in + * which to obtain the value + * + * @param key The optional 'key' to use when setting the + * value into the Session attribute Map + * + * @param value The value to set + */ + public void setValue(HandlerContext context, IODescriptor outDesc, String key, Object value) { + if (key == null) { + // Provide a reasonably unique default + key = context.getHandlerDefinition().getId() + + ':' + outDesc.getName(); + } + + // Get it from the Session attribute map + context.getFacesContext().getExternalContext(). + getSessionMap().put(key, value); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterCreateEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterCreateEvent.java new file mode 100644 index 0000000..75c53e9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterCreateEvent.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class AfterCreateEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public AfterCreateEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterEncodeEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterEncodeEvent.java new file mode 100644 index 0000000..fad3762 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterEncodeEvent.java @@ -0,0 +1,43 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class AfterEncodeEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public AfterEncodeEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterLoopEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterLoopEvent.java new file mode 100644 index 0000000..24b70db --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/AfterLoopEvent.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class AfterLoopEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public AfterLoopEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeCreateEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeCreateEvent.java new file mode 100644 index 0000000..11531cf --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeCreateEvent.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class BeforeCreateEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public BeforeCreateEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeEncodeEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeEncodeEvent.java new file mode 100644 index 0000000..8e91d89 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeEncodeEvent.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class BeforeEncodeEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public BeforeEncodeEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeLoopEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeLoopEvent.java new file mode 100644 index 0000000..73f1fba --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/BeforeLoopEvent.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class BeforeLoopEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public BeforeLoopEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/CommandActionListener.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/CommandActionListener.java new file mode 100644 index 0000000..59fa04a --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/CommandActionListener.java @@ -0,0 +1,275 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.event.ActionListener; + +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.util.LogUtil; + + +/** + *

    The purpose of this class is to provide an ActionListener + * that can delegate to handlers (that are likely defined via XML). It is + * safe to register this class as a managed bean at the Application + * scope. Or to use it directly as an ActionListener.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class CommandActionListener implements ActionListener, Serializable { + + /** + *

    Constructor. It is not recommended this constructor be used, + * however, it is available so that it may be used as a managed + * bean. Instead call {@link #getInstance()}.

    + */ + public CommandActionListener() { + super(); + } + + /** + *

    This delegates to {@link #getInstance(FacesContext)}.

    + */ + public static CommandActionListener getInstance() { + return getInstance(FacesContext.getCurrentInstance()); + } + + /** + *

    This is the preferred way to obtain an instance of this object.

    + */ + public static CommandActionListener getInstance(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + CommandActionListener instance = null; + if (ctx != null) { + instance = (CommandActionListener) ctx.getExternalContext(). + getApplicationMap().get(CAL_INSTANCE); + } + if (instance == null) { + instance = new CommandActionListener(); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put( + CAL_INSTANCE, instance); + } + } + return instance; + } + + /** + *

    This method is invoked, when used directly as an + * ActionListener. + */ + public void processAction(ActionEvent event) { + invokeCommandHandlers(event); + } + + /** + *

    This is an ActionListener that delegates to handlers to process + * the action.

    + */ + public void invokeCommandHandlers(ActionEvent event) { + // Get the UIComponent source associated w/ this command + UIComponent command = (UIComponent) event.getSource(); + if (command == null) { + throw new IllegalArgumentException( + "Action invoked, however, no source was given!"); + } + + // Get the FacesContext + FacesContext context = FacesContext.getCurrentInstance(); + + // Look on the UIComponent for the CommandHandlers + LayoutElement desc = null; + List handlers = (List) + command.getAttributes().get(LayoutComponent.COMMAND); + if ((handlers != null) && (handlers.size() > 0)) { + // This is needed for components that don't have corresponding + // LayoutElements, it is also useful for dynamically defining + // Handlers (advanced and not recommended unless you have a good + // reason). May also happen if "id" for any component in + // hierarchy is not a simple String. + + // No parent (null) or ComponentType, just pass (null) + desc = new LayoutComponent( + (LayoutElement) null, command.getId(), (ComponentType) null); + } else { + // Attempt to find LayoutElement based on command's client id + // "desc" may be null + String viewId = getViewId(command); + desc = findLayoutElementByClientId( + context, viewId, command.getClientId(context)); + if (desc == null) { + // Do a brute force search for the LE + desc = findLayoutElementById(context, viewId, command.getId()); + } + } + + // If We still don't have a desc, we're stuck + if (desc == null) { + throw new IllegalArgumentException( + "Unable to locate handlers for '" + + command.getClientId(context) + "'."); + } + + // Dispatch the Handlers from the LayoutElement + desc.dispatchHandlers(context, COMMAND_EVENT_TYPE, event); + } + + /** + *

    This method returns the "viewId" of the ViewRoot given + * a UIComponent that is part of that + * ViewRoot.

    + */ + public static String getViewId(UIComponent comp) { + String result = null; + while ((comp != null) && !(comp instanceof UIViewRoot)) { + // Searching for the UIViewRoot... + comp = comp.getParent(); + } + if (comp != null) { + // Found the UIViewRoot, get its "ViewId" + result = ((UIViewRoot) comp).getViewId(); + } + // Return the result (or null) + return result; + } + + /** + *

    This method searches for the LayoutComponent that matches the given + * client ID. Although this is often possible, it won't work all the + * time. This is because there is no way to ensure a 1-to-1 mapping + * between the UIComponent and the LayoutComponent tree. A given + * LayoutComponent may create multiple UIComponent, the + * LayoutComponent tree may itself be dynamic, and the UIComponent + * tree may change after it is initially created from the + * LayoutComponent tree. For these reasons, this method may fail. In + * these circumstances, it is critical to store the necessary + * information with the UIComponent itself.

    + */ + public static LayoutElement findLayoutElementByClientId(FacesContext ctx, String layoutDefKey, String clientId) { + LayoutElement result = null; + try { + result = + findLayoutElementByClientId( + LayoutDefinitionManager. + getLayoutDefinition(ctx, layoutDefKey), clientId); + } catch (LayoutDefinitionException ex) { + if (LogUtil.configEnabled()) { + LogUtil.config("Unable to resolve client id '" + clientId + + "' for LayoutDefinition key: '" + + layoutDefKey + "'.", ex); + } + } + return result; + } + + public static LayoutElement findLayoutElementByClientId(LayoutDefinition def, String clientId) { +// FIXME: TBD... +// FIXME: Walk LE tree, ignore non-LayoutComponent entries (this may cause a problem itself b/c of conditional statements & loops) +// FIXME: Handle LayoutCompositions / LayoutInserts + return null; + } + + /** + *

    This method simply searches the LayoutElement tree using the given + * id. As soon as it matches any LayoutElement in the tree w/ the + * given id, it returns it. This method does *not* respect + * NamingContainers as the only information given to this method is a + * simple "id".

    + */ + public static LayoutElement findLayoutElementById(FacesContext ctx, String layoutDefKey, String id) { + // Sanity check + if (id == null) { + return null; + } + + LayoutElement result = null; + try { + result = findLayoutElementById( + LayoutDefinitionManager. + getLayoutDefinition(ctx, layoutDefKey), id); + } catch (LayoutDefinitionException ex) { + if (LogUtil.configEnabled()) { + LogUtil.config("Unable to resolve id '" + id + + "' for LayoutDefinition key: '" + + layoutDefKey + "'.", ex); + } + } + return result; + } + + /** + *

    This method does not evaluate the id field of the LayoutElement + * when checking for a match, this means it will not find values where + * the LayoutComponent's id must be evaulated. Store the handlers on + * the UIComponent in this case.

    + */ + public static LayoutElement findLayoutElementById(LayoutElement elt, String id) { + // First check to see if the given LayoutElement is it + if (elt.getUnevaluatedId().equals(id)) { + return elt; + } + + // Iterate over children and recurse (depth first) + LayoutElement child = null; + Iterator it = elt.getChildLayoutElements().iterator(); + while (it.hasNext()) { + child = it.next(); +// FIXME: Handle LayoutCompositions / LayoutInserts + if (child instanceof LayoutComponent) { + child = findLayoutElementById(child, id); + if (child != null) { + return child; + } + } + } + return null; + } + + /** + * Application scope key for an instance of this class. + */ + private static final String CAL_INSTANCE = "__jsft_CommandActionListener"; + + private static final long serialVersionUID = 2L; + + /** + *

    The "command" event type. ("command")

    + */ + public static final String COMMAND_EVENT_TYPE = "command"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/CreateChildEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/CreateChildEvent.java new file mode 100644 index 0000000..5f92b3e --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/CreateChildEvent.java @@ -0,0 +1,90 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + *

    This event is typically invoked when a factory not only creates a + * component, but creates children under that component. This event may + * be invoked to allow a page author to have greater control over what + * happens during the child creation. See individual factory JavaDocs to + * see which factories support this and what may be done during this + * event.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class CreateChildEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public CreateChildEvent(UIComponent component) { + super(component); + } + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public CreateChildEvent(UIComponent component, Object data) { + super(component); + setData(data); + } + + /** + *

    This method provides access to extra data that is set by the + * creator of this Event. See documentation of the code that fires + * this event to learn what (if anything) is stored here.

    + */ + public Object getData() { + return _data; + } + + /** + *

    This setter allows extending classes to set this value via this + * setter. Normally this value is passed into the constructor.

    + */ + protected void setData(Object data) { + _data = data; + } + + /** + *

    The "createChild" event type. ("createChild")

    + */ + public static final String EVENT_TYPE = "createChild"; + + /** + *

    This value provides extra information that can be associated with + * this event. See code that uses this event to learn more about + * what (if anything) this information is used for.

    + */ + private Object _data = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/DecodeEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/DecodeEvent.java new file mode 100644 index 0000000..b2893d2 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/DecodeEvent.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class DecodeEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public DecodeEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/EncodeEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/EncodeEvent.java new file mode 100644 index 0000000..3c89eee --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/EncodeEvent.java @@ -0,0 +1,44 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class EncodeEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + public EncodeEvent(UIComponent component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/EventObjectBase.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/EventObjectBase.java new file mode 100644 index 0000000..5123825 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/EventObjectBase.java @@ -0,0 +1,79 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import java.util.EventObject; + +import javax.faces.component.UIComponent; + + +/** + *

    This class serves as the base class for EventObjects in + * this package.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class EventObjectBase extends EventObject implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    This constructor should not be used.

    + */ + private EventObjectBase() { + super(null); + } + + /** + *

    This constructor is protected to avoid direct instantiation, one + * of the sub-classes of this class should be used instead.

    + * + * @param component The UIComponent associated with this + * EventObject. + */ + protected EventObjectBase(UIComponent component) { + super(component); + } + + /** + *

    This constructor should only be used when a + * UIComponent is not available.

    + */ + protected EventObjectBase(Object obj) { + super(obj); + } + + /** + *

    This method returns the UIComponent held by the + * Object implementing this interface (or null if the + * event source is not a UIComponent).

    + * + * @return The UIComponent. + */ + public UIComponent getUIComponent() { + Object source = getSource(); + if (source instanceof UIComponent) { + return (UIComponent) getSource(); + } + return null; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/InitPageEvent.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/InitPageEvent.java new file mode 100644 index 0000000..ce237e4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/InitPageEvent.java @@ -0,0 +1,47 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + + + +/** + *

    This event is fired for each page accessed during each request. This + * may be fired during the UIComponent tree creation time, while restoring + * the View, when forwarding to a new page, or when simply accessing a + * page via Java code.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class InitPageEvent extends EventObjectBase implements UIComponentHolder { + private static final long serialVersionUID = 1L; + + /** + *

    Constructor.

    + * + * @param component The UIComponent associated with this + * EventObject (likely null). + */ + public InitPageEvent(Object component) { + super(component); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/UIComponentHolder.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/UIComponentHolder.java new file mode 100644 index 0000000..7a9c485 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/UIComponentHolder.java @@ -0,0 +1,46 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import javax.faces.component.UIComponent; + + +/** + *

    This interface defines a method for obtaining a + * UIComponent. This is used by various + * EventObject implementations which hold + * UIComponent. This allows event handling code to access + * the UIComponent related to the event.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface UIComponentHolder { + + /** + *

    This method returns the UIComponent held by the + * Object implementing this interface.

    + * + * @return The UIComponent. + */ + public UIComponent getUIComponent(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/ValueChangeListener.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/ValueChangeListener.java new file mode 100644 index 0000000..4d69f03 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/event/ValueChangeListener.java @@ -0,0 +1,284 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.event; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.event.ValueChangeEvent; + +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.util.LogUtil; + + +/** + *

    This class provides a ValueChangeListener that can + * delegate to handlers (that are likely defined via the template). It + * is safe to register this class as a managed bean at the Application + * scope. Or to use it directly as a + * ValueChangeListener.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ValueChangeListener implements javax.faces.event.ValueChangeListener, Serializable { + + /** + *

    Constructor. It is not recommended this constructor be used, + * however, it is available so that it may be used as a managed + * bean. Instead call {@link #getInstance()}.

    + */ + public ValueChangeListener() { + super(); + } + + /** + *

    This delegates to {@link #getInstance(FacesContext)}.

    + */ + public static ValueChangeListener getInstance() { + return getInstance(FacesContext.getCurrentInstance()); + } + + /** + *

    This is the preferred way to obtain an instance of this object.

    + */ + public static ValueChangeListener getInstance(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + ValueChangeListener instance = null; + if (ctx != null) { + instance = (ValueChangeListener) ctx.getExternalContext(). + getApplicationMap().get(VCL_INSTANCE); + } + if (instance == null) { + instance = new ValueChangeListener(); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put( + VCL_INSTANCE, instance); + } + } + return instance; + } + + /** + *

    This method is invoked, when used directly as a + * ValueChangeListener. + */ + public void processValueChange(ValueChangeEvent event) { + invokeValueChangeHandlers(event); + } + + /** + *

    This is an ValueChangeListener that delegates to handlers to + * process the action.

    + */ + public void invokeValueChangeHandlers(ValueChangeEvent event) { + // Get the UIComponent (evh) source associated w/ this valueChangeEvent + UIComponent evh = (UIComponent) event.getSource(); + if (evh == null) { + throw new IllegalArgumentException( + "ValueChange invoked, however, no source was given!"); + } + + // Get the FacesContext + FacesContext context = FacesContext.getCurrentInstance(); + + // Look on the UIComponent for the ValueChangeHandlers + LayoutElement desc = null; + List handlers = (List) + evh.getAttributes().get(VALUE_CHANGE); + if ((handlers != null) && (handlers.size() > 0)) { + // This is needed for components that don't have corresponding + // LayoutElements, it is also useful for dynamically defining + // Handlers (advanced and not recommended unless you have a good + // reason). May also happen if "id" for any component in + // hierarchy is not a simple String. + + // No parent (null) or ComponentType, just pass (null) + desc = new LayoutComponent( + (LayoutElement) null, evh.getId(), (ComponentType) null); + } else { + // Attempt to find LayoutElement based on evh's client id + // "desc" may be null + String viewId = getViewId(evh); + desc = findLayoutElementByClientId( + context, viewId, evh.getClientId(context)); + if (desc == null) { + // Do a brute force search for the LE + desc = findLayoutElementById(context, viewId, evh.getId()); + } + } + + // If We still don't have a desc, we're stuck + if (desc == null) { + throw new IllegalArgumentException( + "Unable to locate handlers for '" + + evh.getClientId(context) + "'."); + } + + // Dispatch the Handlers from the LayoutElement + desc.dispatchHandlers(context, VALUE_CHANGE, event); + } + + /** + *

    This method returns the "viewId" of the ViewRoot given + * a UIComponent that is part of that + * ViewRoot.

    + */ + public static String getViewId(UIComponent comp) { +// FIXME: This should be a util method. (Same as CommandActionListener) + String result = null; + while ((comp != null) && !(comp instanceof UIViewRoot)) { + // Searching for the UIViewRoot... + comp = comp.getParent(); + } + if (comp != null) { + // Found the UIViewRoot, get its "ViewId" + result = ((UIViewRoot) comp).getViewId(); + } + // Return the result (or null) + return result; + } + + /** + *

    This method searches for the LayoutComponent that matches the given + * client ID. Although this is often possible, it won't work all the + * time. This is because there is no way to ensure a 1-to-1 mapping + * between the UIComponent and the LayoutComponent tree. A given + * LayoutComponent may create multiple UIComponent, the + * LayoutComponent tree may itself be dynamic, and the UIComponent + * tree may change after it is initially created from the + * LayoutComponent tree. For these reasons, this method may fail. In + * these circumstances, it is critical to store the necessary + * information with the UIComponent itself.

    + */ + public static LayoutElement findLayoutElementByClientId(FacesContext ctx, String layoutDefKey, String clientId) { +// FIXME: This should be a util method. (Same as CommandActionListener) + LayoutElement result = null; + try { + result = + findLayoutElementByClientId( + LayoutDefinitionManager. + getLayoutDefinition(ctx, layoutDefKey), clientId); + } catch (LayoutDefinitionException ex) { + if (LogUtil.configEnabled()) { + LogUtil.config("Unable to resolve client id '" + clientId + + "' for LayoutDefinition key: '" + + layoutDefKey + "'.", ex); + } + } + return result; + } + + public static LayoutElement findLayoutElementByClientId(LayoutDefinition def, String clientId) { +// FIXME: This should be a util method. (Same as CommandActionListener) +// +// FIXME: TBD... +// FIXME: Walk LE tree, ignore non-LayoutComponent entries (this may cause a problem itself b/c of conditional statements & loops) +// FIXME: Handle LayoutCompositions / LayoutInserts + return null; + } + + /** + *

    This method simply searches the LayoutElement tree using the given + * id. As soon as it matches any LayoutElement in the tree w/ the + * given id, it returns it. This method does *not* respect + * NamingContainers as the only information given to this method is a + * simple "id".

    + */ + public static LayoutElement findLayoutElementById(FacesContext ctx, String layoutDefKey, String id) { +// FIXME: This should be a util method. (Same as CommandActionListener) + // Sanity check + if (id == null) { + return null; + } + + LayoutElement result = null; + try { + result = findLayoutElementById( + LayoutDefinitionManager. + getLayoutDefinition(ctx, layoutDefKey), id); + } catch (LayoutDefinitionException ex) { + if (LogUtil.configEnabled()) { + LogUtil.config("Unable to resolve id '" + id + + "' for LayoutDefinition key: '" + + layoutDefKey + "'.", ex); + } + } + return result; + } + + /** + *

    This method does not evaluate the id field of the LayoutElement + * when checking for a match, this means it will not find values where + * the LayoutComponent's id must be evaulated. Store the handlers on + * the UIComponent in this case.

    + */ + public static LayoutElement findLayoutElementById(LayoutElement elt, String id) { +// FIXME: This should be a util method. (Same as CommandActionListener) + // First check to see if the given LayoutElement is it + if (elt.getUnevaluatedId().equals(id)) { + return elt; + } + + // Iterate over children and recurse (depth first) + LayoutElement child = null; + Iterator it = elt.getChildLayoutElements().iterator(); + while (it.hasNext()) { + child = it.next(); +// FIXME: Handle LayoutCompositions / LayoutInserts + if (child instanceof LayoutComponent) { + child = findLayoutElementById(child, id); + if (child != null) { + return child; + } + } + } + return null; + } + + + /** + * Application scope key for an instance of this class. + */ + private static final String VCL_INSTANCE = "__jsft_ValueChangeListener"; + + private static final long serialVersionUID = 2L; + + /** + *

    This is the "event type" for handlers to be invoked to handle + * value change event for this component.

    + */ + public static final String VALUE_CHANGE = "valueChange"; + +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/DbFactory.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/DbFactory.java new file mode 100644 index 0000000..63ffabb --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/DbFactory.java @@ -0,0 +1,43 @@ +/** + * + */ +package com.sun.jsftemplating.layout.facelets; + +import com.sun.jsftemplating.layout.xml.XMLErrorHandler; + +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +/** + * This class provides a convenient way to create a DocumentBuilder using the + * JSFTemplating entity resolver. + * @author Jason Lee + * + */ +public class DbFactory { + public static DocumentBuilder getInstance() throws ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(false); + factory.setIgnoringComments(true); + factory.setIgnoringElementContentWhitespace(false); + factory.setCoalescing(false); + factory.setExpandEntityReferences(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + try { + builder.setErrorHandler(new XMLErrorHandler(new PrintWriter( + new OutputStreamWriter(System.err, "UTF-8"), true))); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException(ex); + } + + builder.setEntityResolver(new FaceletsClasspathEntityResolver()); + + return builder; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsClasspathEntityResolver.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsClasspathEntityResolver.java new file mode 100644 index 0000000..a4de9e4 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsClasspathEntityResolver.java @@ -0,0 +1,18 @@ +/** + * + */ +package com.sun.jsftemplating.layout.facelets; + +import com.sun.jsftemplating.util.ClasspathEntityResolver; +import org.xml.sax.InputSource; + +/** + * @author Jason Lee + * + */ +public class FaceletsClasspathEntityResolver extends ClasspathEntityResolver { + public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) { + String grammarName = systemId.substring(systemId.lastIndexOf('/') + 1); + return super.resolveEntity(name, publicId, baseURI, grammarName); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionManager.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionManager.java new file mode 100644 index 0000000..84ff7ab --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionManager.java @@ -0,0 +1,170 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.facelets; + +import com.sun.jsftemplating.annotation.FormatDefinition; +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.template.TemplateParser; +import com.sun.jsftemplating.util.FileUtil; + +import java.io.IOException; +import java.net.URL; + +import javax.faces.context.FacesContext; + + +/** + * + * @author Jason Lee + * @author Ken Paulsen + */ +@FormatDefinition +public class FaceletsLayoutDefinitionManager extends LayoutDefinitionManager { + + /** + * Default Constructor. + */ + public FaceletsLayoutDefinitionManager() { + super(); + } + + @Override + public boolean accepts(String key) { + boolean accept = false; + URL url = null; + try { + url = FileUtil.searchForFile(key, defaultSuffix); + } catch (IOException ex) { + // Ignore this b/c we're just trying to detect if we're the right + // LDM... if we're here, probably we're not. + } + if (url == null) { + return false; + } + + // Eventually, we may want this check to be configurable via a + // context-param... + if (url.getPath().contains(".xhtml")) { + accept = true; + } else { + // Use the TemplateParser to help us read the file to see if it is a + // valid XML-format file + TemplateParser parser = new TemplateParser(url); + accept = true; + try { + parser.open(); + parser.readUntil("=\"http://java.sun.com/jsf/facelets\"", true); + } catch (Exception ex) { + // Didn't work... + accept = false; + } finally { + parser.close(); + } + } + + return accept; + } + + /** + *

    This method is responsible for finding the requested + * {@link LayoutDefinition} for the given key.

    + * + * @param key Key identifying the desired {@link LayoutDefinition}. + * + * @return The requested {@link LayoutDefinition}. + */ + public LayoutDefinition getLayoutDefinition(String key) throws LayoutDefinitionException { + // Make sure we found the url + URL url = null; + try { + url = FileUtil.searchForFile(key, defaultSuffix); + } catch (IOException ex) { + throw new LayoutDefinitionException( + "Unable to locate '" + key + "'", ex); + } + if (url == null) { + throw new LayoutDefinitionException( + "Unable to locate '" + key + "'"); + } + + // Read the template file + LayoutDefinition ld = null; + try { + ld = new FaceletsLayoutDefinitionReader(key, url).read(); + } catch (IOException ex) { + throw new LayoutDefinitionException( + "Unable to process '" + url.toString() + "'.", ex); + } + + // Dispatch "initPage" handlers + ld.dispatchInitPageHandlers(FacesContext.getCurrentInstance(), ld); + + // Return the LayoutDefinition + return ld; + } + + /** + *

    This method returns an instance of this LayoutDefinitionManager. + * The object returned is a singleton (only 1 instance will be + * created per application).

    + * + * @return FaceletsLayoutDefinitionManager instance + */ + public static LayoutDefinitionManager getInstance() { + return getInstance(FacesContext.getCurrentInstance()); + } + + /** + *

    This method provides access to the application-scoped instance + * of the FaceletsLayoutDefinitionManager.

    + * + * @param ctx The FacesContext (may be null). + */ + public static LayoutDefinitionManager getInstance(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + FaceletsLayoutDefinitionManager instance = null; + if (ctx != null) { + instance = (FaceletsLayoutDefinitionManager) + ctx.getExternalContext().getApplicationMap().get(FLDM_INSTANCE); + } + if (instance == null) { + instance = new FaceletsLayoutDefinitionManager(); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put( + FLDM_INSTANCE, instance); + } + } + return instance; + } + + /** + *

    Application scope key for an instance of this class.

    + */ + private static final String FLDM_INSTANCE = "__jsft_FaceletsLDM"; + + private static final String defaultSuffix = ".xhtml"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionReader.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionReader.java new file mode 100644 index 0000000..4866617 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionReader.java @@ -0,0 +1,458 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.facelets; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import javax.xml.parsers.DocumentBuilder; + +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutComposition; +import com.sun.jsftemplating.layout.descriptors.LayoutDefine; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.LayoutFacet; +import com.sun.jsftemplating.layout.descriptors.LayoutForEach; +import com.sun.jsftemplating.layout.descriptors.LayoutIf; +import com.sun.jsftemplating.layout.descriptors.LayoutInsert; +import com.sun.jsftemplating.layout.descriptors.LayoutStaticText; +import com.sun.jsftemplating.layout.template.BaseProcessingContext; +import com.sun.jsftemplating.layout.template.EventParserCommand; +import com.sun.jsftemplating.layout.template.ProcessingContextEnvironment; +import com.sun.jsftemplating.layout.template.TemplateParser; +import com.sun.jsftemplating.layout.template.TemplateReader; +import com.sun.jsftemplating.util.IncludeInputStream; +import com.sun.jsftemplating.util.LayoutElementUtil; +import com.sun.jsftemplating.util.Util; + +import javax.faces.FactoryFinder; +import javax.faces.application.Application; +import javax.faces.application.ApplicationFactory; + + +/** + * @author Jason Lee + * + */ +public class FaceletsLayoutDefinitionReader { + private URL url; + private String key; + private Document document; + private int _idNumber; + + public FaceletsLayoutDefinitionReader(String key, URL url) { + _idNumber = LayoutElementUtil.getStartingIdNumber(null, key); + InputStream is = null; + BufferedInputStream bs = null; + try{ + this.key = key; + this.url = url; + + DocumentBuilder builder = DbFactory.getInstance(); + builder.setErrorHandler(new ParsingErrorHandler()); + is = this.url.openStream(); + bs = new BufferedInputStream(is); + document = builder.parse(new IncludeInputStream(bs)); + } catch (Exception e) { + throw new LayoutDefinitionException(e); + } finally { + Util.closeStream(bs); + Util.closeStream(is); + } + } + + public LayoutDefinition read() throws IOException { + LayoutDefinition layoutDefinition = new LayoutDefinition(key); + NodeList nodeList = document.getChildNodes(); + boolean abortProcessing = false; + DocumentType docType = document.getDoctype(); + if (docType != null) { + LayoutStaticText stDocType = new LayoutStaticText(layoutDefinition, "", + ""); + layoutDefinition.addChildLayoutElement(stDocType); + } + for (int i = 0; i < nodeList.getLength() && (abortProcessing != true); i++) { + abortProcessing = process(layoutDefinition, nodeList.item(i), false); + } + return layoutDefinition; + } + + public boolean process(LayoutElement parent, Node node, boolean nested) throws IOException { + boolean abortProcessing = false; + LayoutElement element = null; + LayoutElement newParent = parent; + boolean endElement = false; + + String value = node.getNodeValue(); +// TODO: find out what "name" should be in the ctors + switch (node.getNodeType()) { + case Node.TEXT_NODE : + if (!value.trim().equals("")) { + element = new LayoutStaticText(parent, + LayoutElementUtil.getGeneratedId(node.getNodeName(), getNextIdNumber()), + value); + } + break; + case Node.ELEMENT_NODE: + element = createComponent(parent, node, nested); + if (element instanceof LayoutStaticText) { + // We have a element node that needs to be static text + endElement = true; + } else if (element instanceof LayoutForEach) { + newParent = element; + } else if (element instanceof LayoutIf) { + newParent = element; + } else if (element instanceof LayoutComponent) { + nested = true; + newParent = element; + } else if (element instanceof LayoutComposition) { + abortProcessing = ((LayoutComposition)element).isTrimming(); + newParent = element; + } else if (element instanceof LayoutDefine) { + newParent = element; + } else if (element instanceof LayoutFacet) { + newParent = element; + } else if (element instanceof LayoutInsert) { + newParent = element; + } +// FIXME: Jason, this code may need to be refactored. I think almost +// FIXME: everything should have newParent = element. The problem comes when +// FIXME: you are turning and into 2 separate staticText +// FIXME: components. This should be a single component, then it could contain +// FIXME: children also. You may want a to create a component like Woodstock's +// FIXME: "markup" component to do this. + break; + default: + // just because... :P + } + + if (element != null) { + parent.addChildLayoutElement(element); + + NodeList nodeList = node.getChildNodes(); + boolean abortChildProcessing = false; + for (int i = 0; i < nodeList.getLength() && (abortChildProcessing != true); i++) { + abortChildProcessing = process(newParent, nodeList.item(i), nested); + } + if (abortChildProcessing == true) { + abortProcessing = abortChildProcessing; + }else { + + if (endElement) { + String nodeName = node.getNodeName(); + element = new LayoutStaticText(parent, LayoutElementUtil.getGeneratedId(nodeName, getNextIdNumber()), ""); + parent.addChildLayoutElement(element); + } + } + } + + return abortProcessing; + } + + private LayoutComposition processComposition(LayoutElement parent, String attrName, NamedNodeMap attrs, String id, boolean trimming) { + LayoutComposition lc = new LayoutComposition(parent, id); + lc.setTrimming(trimming); + if (trimming) { + parent = parent.getLayoutDefinition(); // parent to the LayoutDefinition + parent.getChildLayoutElements().clear(); // a ui:composition clears everything outside of it + } + Node fileNameNode = attrs.getNamedItem(attrName); + String fileName = (fileNameNode != null) ? fileNameNode.getNodeValue() : null; + lc.setTemplate(fileName); + + return lc; + } + + private LayoutComponent processComponent(LayoutElement parent, Node node, NamedNodeMap attrs, String id, boolean trimming) { + if (trimming) { + parent = parent.getLayoutDefinition(); // parent to the LayoutDefinition + parent.getChildLayoutElements().clear(); // a ui:composition clears everything outside of it + } + LayoutComponent lc = new LayoutComponent(parent, id, + LayoutDefinitionManager.getGlobalComponentType(null, "event")); + parent.addChildLayoutElement(lc); + LayoutComposition comp = processComposition(lc, "template", attrs, id+"_lc", trimming); + + NodeList nodeList = node.getChildNodes(); + boolean abortChildProcessing = false; + for (int i = 0; i < nodeList.getLength() && (abortChildProcessing != true); i++) { + try { + abortChildProcessing = process(comp, nodeList.item(i), true); + } catch (IOException e) { + e.printStackTrace(); + } + } + lc.addChildLayoutElement(comp); + + return lc; + } + +/* +This code is not used and does not appear to be correct, it should use FacesContext.getApplication() + private Application getApplication() { + ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder + .getFactory(FactoryFinder.APPLICATION_FACTORY); + return appFactory.getApplication(); + } + + private Object getElValue(String el) { + FacesContext context = FacesContext.getCurrentInstance(); + return getApplication() + .evaluateExpressionGet(context, el, Object.class); + } +*/ + + + private LayoutElement createComponent(LayoutElement parent, Node node, boolean nested) { + LayoutElement element = null; + String nodeName = node.getNodeName(); + NamedNodeMap attrs = node.getAttributes(); + Node nameNode = attrs.getNamedItem("id"); + String id = (nameNode != null) ? nameNode.getNodeValue() : + LayoutElementUtil.getGeneratedId(nodeName, getNextIdNumber()); + + if ("ui:composition".equals(nodeName)) { + element = processComposition(parent, "template", attrs, id, true); + } else if ("ui:decorate".equals(nodeName)) { + element = processComposition(parent, "template", attrs, id, false); + } else if ("ui:define".equals(nodeName)) { + String name = attrs.getNamedItem("name").getNodeValue(); + element = new LayoutDefine(parent, name); + } else if ("ui:insert".equals(nodeName)) { + LayoutInsert li = new LayoutInsert(parent, id); + Node nameAttr = attrs.getNamedItem("name"); + String name = (nameAttr != null) ? nameAttr.getNodeValue() : null; + li.setName(name); + element = li; + // Let these be handled by the else below, and let's see what happens :) + } else if ("ui:component".equals(nodeName)) { + element = processComponent(parent, node, attrs, id, true); + } else if ("ui:fragment".equals(nodeName)) { + element = processComponent(parent, node, attrs, id, false); + /* + Node bindingAttr = attrs.getNamedItem("binding"); + if (bindingAttr == null) { + throw new LayoutDefinitionException("ui:fragment requires a binding attribute"); + } + String bindingEl = bindingAttr.getNodeValue(); + Object obj = getElValue(bindingEl); + if (!(obj instanceof UIComponent)) { + throw new LayoutDefinitionException("Binding EL must return a UIComponent"); + } + UIComponent comp = (UIComponent) obj; + String family = comp.getFamily(); // TODO: is the correct? + System.out.println(LayoutDefinitionManager.getGlobalComponentTypes(null)); + ComponentType componentType = + LayoutDefinitionManager.getGlobalComponentType(null, family); + LayoutComponent lc = new LayoutComponent(parent, id, componentType); + addAttributesToComponent(lc, node); + lc.setFacetChild(false); + lc.setNested(nested); + element = lc; + */ + } else if ("ui:debug".equals(nodeName)) { + } else if ("ui:include".equals(nodeName)) { + element = processComposition(parent, "src", attrs, id, false); + } else if ("ui:param".equals(nodeName)) { + // Handle "param" + Node nameAttNode = attrs.getNamedItem("name"); + if (nameAttNode == null) { + throw new SyntaxException("The 'name' attribute is required on 'param'."); + } + Node valueNode = attrs.getNamedItem("value"); + if (valueNode == null) { + throw new SyntaxException("The 'value' attribute is required on 'param'."); + } + + // For now only handle cases where the parent is a LayoutComposition + if (!(parent instanceof LayoutComposition)) { + throw new SyntaxException("<" + nodeName + + " name='" + nameAttNode.getNodeValue() + + "' value='" + valueNode.getNodeValue() + + "'> must be child of a 'composition' element!"); + } + // Set the name=value on the parent LayoutComposition + ((LayoutComposition) parent).setParameter( + nameAttNode.getNodeValue(), valueNode.getNodeValue()); + } else if ("ui:remove".equals(nodeName)) { + // Let the element remain null + } else if ("ui:repeat".equals(nodeName)) { + } else if ("ui:event".equals(nodeName)) { + // per Ken, we need to append "/>" to allow the handler parser code + // to end correctly + String body = node.getTextContent(); + body = (body == null) ? "/>" : (body.trim() + "/>"); + Node type = node.getAttributes().getNamedItem("type"); + if (type == null) { + // Ensure type != null + throw new SyntaxException( + "The 'type' attribute is required on 'ui:event'!"); + } + String eventName = type.getNodeValue(); + InputStream is = new ByteArrayInputStream(body.getBytes()); + EventParserCommand command = new EventParserCommand(); + try { + TemplateParser parser = new TemplateParser(is); + parser.open(); // Needed to initialize things. + // Setup the reader... + TemplateReader reader = new TemplateReader("foo", parser); // TODO: get a real ID + reader.pushTag("event"); // The tag will be popped at the end + // Read the handlers... + command.process(new BaseProcessingContext(), + new ProcessingContextEnvironment(reader, parent, true), eventName); + // Clean up + parser.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + // ignore + } + } + } + } else if ("ui:if".equals(nodeName)) { + // Handle "if" conditions + String condition = attrs.getNamedItem("condition").getNodeValue(); + element = new LayoutIf(parent, condition); + } else if ("ui:foreach".equals(nodeName)) { + // Handle "foreach" conditions + Node valueNode = attrs.getNamedItem("value"); + if (valueNode == null) { + throw new SyntaxException("The 'value' property is required on 'foreach'."); + } + Node varNode = attrs.getNamedItem("var"); + if (varNode == null) { + throw new SyntaxException("The 'var' property is required on 'foreach'."); + } + + element = new LayoutForEach(parent, valueNode.getNodeValue(), varNode.getNodeValue()); + } else if ("f:facet".equals(nodeName)) { + // FIXME: Need to take NameSpace into account + nameNode = attrs.getNamedItem("name"); + if (nameNode == null) { + throw new IllegalArgumentException("You must provide a name " + + "attribute for all facets! Parent component is: '" + + parent.getUnevaluatedId() + "'."); + } + LayoutFacet facetElt = new LayoutFacet(parent, nameNode.getNodeValue()); + + // Determine if this is a facet place holder (i.e. we're defining + // a renderer w/ a facet), or if it is a facet value to set on a + // containing component. + boolean isRendered = + !LayoutElementUtil.isNestedLayoutComponent(facetElt); + facetElt.setRendered(isRendered); + element = facetElt; + } else { + LayoutComponent lc = null; + ComponentType componentType = null; + String nsURI = node.getNamespaceURI(); + if (nsURI != null) { + // Do lookup using namespace... + componentType = LayoutDefinitionManager.getGlobalComponentType( + null, nsURI + ':' + node.getLocalName()); + } + if (componentType == null) { + // Try w/o using namespace + componentType = LayoutDefinitionManager. + getGlobalComponentType(null, nodeName); + } + if (componentType == null) { + String value = node.getNodeValue(); + if (value == null) { + value = ""; + } +// FIXME: This needs to account for beginning and ending tags.... + lc = new LayoutStaticText(parent, id, + "<" + nodeName + buildAttributeList(node) + ">"); + } else { + lc = new LayoutComponent(parent, id, componentType); + addAttributesToComponent(lc, node); + } + lc.setNested(nested); +// FIXME: Because of the way pages are composed in facelets, the parent +// FIXME: LayoutComponent may not exist in this LD. In that case it is not +// FIXME: a "facet child", but it appears to be according to the following +// FIXME: method. We need a better way to mark children as facets or real +// FIXME: children. This may even require diverging the LD into 1 for +// FIXME: components and 1 for pages. :( + //LayoutElementUtil.checkForFacetChild(parent, lc); + //lc.setFacetChild(false); This is done by checkForFacetChild(...) + element = lc; + } + + return element; + } + + private void addAttributesToComponent (LayoutComponent lc, Node node) { + NamedNodeMap map = node.getAttributes(); + for (int i = 0; i < map.getLength(); i++) { + Node attr = map.item(i); + lc.addOption(attr.getNodeName(), attr.getNodeValue()); + } + } + + private String buildAttributeList(Node node) { + StringBuilder attrs = new StringBuilder(); + + NamedNodeMap map = node.getAttributes(); + for (int i = 0; i < map.getLength(); i++) { + Node attr = map.item(i); + attrs.append(" ") + .append(attr.getNodeName()) + .append("=\"") + .append(attr.getNodeValue()) + .append("\""); + } + + return attrs.toString(); + } + + /** + *

    This method returns the next ID number. Calling this method will + * increment the id number.

    + */ + public int getNextIdNumber() { + // Make sure we increment the global counter, if appropriate + LayoutElementUtil.incHighestId(_idNumber); + return _idNumber++; + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/NSContext.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/NSContext.java new file mode 100644 index 0000000..d2b63cd --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/NSContext.java @@ -0,0 +1,128 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.facelets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.xml.XMLConstants; + + +/** + *

    This class provides namespace support for facelets taglib.xml + * files.

    + * + * @author Ken Paulsen + */ +public class NSContext implements javax.xml.namespace.NamespaceContext { + + /** + *

    Creates a default NSContext.

    + */ + public NSContext() { + addNamespace("xml", XMLConstants.XML_NS_URI); + addNamespace("xmlns", XMLConstants.XMLNS_ATTRIBUTE_NS_URI); + } + + /** + *

    Returns the namespace for the given prefix.

    + * + * @throws IllegalArgumentException If null prefix is given. + */ + public String getNamespaceURI(String prefix) { + if (prefix == null) { + throw new IllegalArgumentException("null is not allowed."); + } + String result = _uris.get(prefix); + if (result == null) { + if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) { + result = _defaultNSURI; + } + if (result == null) { + result = XMLConstants.NULL_NS_URI; + } + } + return result; + } + + /** + *

    Returns the prefix for the given namespace. If not mapped, + * null is returned.

    + * + * @throws IllegalArgumentException If null prefix is given. + */ + public String getPrefix(String namespaceURI) { + if (namespaceURI == null) { + throw new IllegalArgumentException("null is not allowed."); + } + String result = _prefixes.get(namespaceURI); + if (result == null) { + if (namespaceURI.equals(_defaultNSURI)) { + result = XMLConstants.DEFAULT_NS_PREFIX; + } + } + return result; + } + + /** + *

    This implementation doesn't support this functionality. Instead + * returns the same result as {@link #getPrefix(String)} via an + * Iterator.

    + */ + public Iterator getPrefixes(String namespaceURI) { + ArrayList list = new ArrayList(); + list.add(getPrefix(namespaceURI)); + return list.iterator(); + } + + /** + *

    This method sets the default NS URI to be used when the default + * prefix (XMLConstants.DEFAULT_NS_PREFIX) is + * supplied.

    + */ + public void setDefaultNSURI(String defaultNSURI) { + _defaultNSURI = defaultNSURI; + } + + /** + *

    This method returns the default NS URI (null if not set).

    + */ + public String getDefaultNSURI() { + return _defaultNSURI; + } + + /** + *

    This method registers a Namespace mapping.

    + */ + public void addNamespace(String prefix, String uri) { + _uris.put(prefix, uri); + _prefixes.put(uri, prefix); + } + + private String _defaultNSURI = null; + + private Map _uris = new HashMap(); + private Map _prefixes = new HashMap(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/ParsingErrorHandler.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/ParsingErrorHandler.java new file mode 100644 index 0000000..7df3d11 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/facelets/ParsingErrorHandler.java @@ -0,0 +1,36 @@ +/** + * + */ +package com.sun.jsftemplating.layout.facelets; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * @author Jason Lee + * + */ +public class ParsingErrorHandler implements ErrorHandler { + //Log logger = LogFactory.getLog(this.getClass()); + + public ParsingErrorHandler() { + super(); + } + + public void warning(SAXParseException arg0) throws SAXException { +// logger.warn(arg0.getMessage()); + } + + public void error(SAXParseException arg0) throws SAXException { + //logger.error(arg0.getMessage()); + fatalError(arg0); + } + + public void fatalError(SAXParseException arg0) throws SAXException { +// logger.error(arg0.getMessage()); + System.err.println (arg0.getMessage()); +// System.exit(-1); + } + +} \ No newline at end of file diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/BaseProcessingContext.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/BaseProcessingContext.java new file mode 100644 index 0000000..62ace36 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/BaseProcessingContext.java @@ -0,0 +1,156 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import java.io.IOException; + +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.LayoutStaticText; +import com.sun.jsftemplating.util.LayoutElementUtil; +import com.sun.jsftemplating.util.Util; + + +/** + *

    Since many contexts share common functionality (i.e. processing static + * text elements), it makes sense to have a base {@link ProcessingContext} + * which may be specialized as needed.

    + */ +public class BaseProcessingContext implements ProcessingContext { + + /** + *

    This is called when a component tag is found + * (<tagname ...).

    + */ + public void beginComponent(ProcessingContextEnvironment env, String content) throws IOException { + // We have a UIComponent tag... first get the parser + // Skip white Space + TemplateReader reader = env.getReader(); + TemplateParser parser = reader.getTemplateParser(); + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + +// tagStack.push(content); + // Create the LayoutComponent + LayoutElement parent = env.getParent(); + LayoutComponent child = reader.createLayoutComponent( + parent, env.isNested(), content); + parent.addChildLayoutElement(child); + + // See if this is a single tag or if there is a closing tag + boolean single = false; + int ch = parser.nextChar(); + if (ch == '/') { + // Single Tag + ch = parser.nextChar(); // Throw away '>' + single = true; + reader.popTag(); // Don't look for ending tag + } + if (ch != '>') { + throw new SyntaxException( + "Expected '>' found '" + (char) ch + "'."); + } + + if (single) { + // This is also the end of the component in this case... + endComponent(env, content); + } else { + // Process child LayoutElements (recurse) + reader.process( + TemplateReader.LAYOUT_COMPONENT_CONTEXT, child, true); + } + } + + /** + *

    This is called when an end component tag is found (</tagname> + * or <tagname ... />). Because it may be called for either of + * the above syntaxes, the caller of this method is responsible for + * maintaining the parser position, this method (or its subclasses) + * should not effect the parser position.

    + */ + public void endComponent(ProcessingContextEnvironment env, String content) throws IOException { + } + + /** + *

    This is called when a special tag is found (<!tagname ...).

    + */ + public void beginSpecial(ProcessingContextEnvironment env, String content) throws IOException { + CustomParserCommand command = + env.getReader().getCustomParserCommand(content); + if (command == null) { + // If there is no Custom command for this, use the default... + command = TemplateReader.EVENT_PARSER_COMMAND; + } + command.process(this, env, content); + } + + /** + *

    This is called when a special end tag is found (</tagname ... or + * <!tagname ... />).

    + */ + public void endSpecial(ProcessingContextEnvironment env, String content) throws IOException { + } + + /** + *

    This is called when static text is found (").

    + */ + public void staticText(ProcessingContextEnvironment env, String content) throws IOException { + LayoutElement parent = env.getParent(); + + // Create a LayoutStaticText + LayoutComponent child = new LayoutStaticText( + parent, + LayoutElementUtil.getGeneratedId( + "txt", env.getReader().getNextIdNumber()), + content); + child.addOption("value", content); + child.setNested(env.isNested()); + + parent.addChildLayoutElement(child); + } + + /** + *

    This is called when escaped static text is found ('). The + * difference between this and staticText is that HTML is expected to + * be escaped so the browser does not parse it.

    + */ + public void escapedStaticText(ProcessingContextEnvironment env, String content) throws IOException { + staticText(env, Util.htmlEscape(content)); + } + + /** + *

    This method is invoked when nothing else matches.

    + * + *

    This implementation reads a character and does nothing with it.

    + */ + public void handleDefault(ProcessingContextEnvironment env, String content) throws IOException { + env.getReader().getTemplateParser().nextChar(); + } + + /** + *

    This is a static reference to the "staticText" + * {@link ComponentType}.

    + public static final ComponentType STATIC_TEXT = + LayoutDefinitionManager.getGlobalComponentType(null, "staticText"); + */ +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/CompositionParserCommand.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/CompositionParserCommand.java new file mode 100644 index 0000000..9db223f --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/CompositionParserCommand.java @@ -0,0 +1,170 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.layout.ProcessingCompleteException; +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.LayoutComposition; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.util.LayoutElementUtil; + +import java.io.IOException; +import java.util.List; + + +/** + *

    This {@link CustomParserCommand} handles "composition" statements. + * TBD... + *

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class CompositionParserCommand implements CustomParserCommand { + + /** + *

    Constructor. This constructor requires a flag to be passed in + * indicating wether content outside this component should be ignored + * (trimmed) or left alone.

    + * + * @param trim true if content outside this component + * should be thrown away. + * + * @param templateAttName The name of the attribute for the template name. + */ + public CompositionParserCommand(boolean trim, String templateAttName) { + this.trimming = trim; + this.templateAttName = templateAttName; + } + + /** + *

    This method processes a "custom" command. These are commands that + * start with a !. When this method receives control, the + * name (i.e. the token after the '!' character) has + * already been read. It is passed via the name + * parameter.

    + * + *

    The {@link ProcessingContext} and + * {@link ProcessingContextEnvironment} are both available.

    + */ + public void process(ProcessingContext ctx, ProcessingContextEnvironment env, String name) throws IOException { + // Get the reader + TemplateReader reader = env.getReader(); + + LayoutElement parent = env.getParent(); + if (trimming) { + // First remove the current children on the LD (trimming == true) + parent = parent.getLayoutDefinition(); + parent.getChildLayoutElements().clear(); + } + + // Next get the attributes + List nvps = + reader.readNameValuePairs(name, templateAttName, true); + + // Create new LayoutComposition + LayoutComposition compElt = new LayoutComposition( + parent, + LayoutElementUtil.getGeneratedId(name, reader.getNextIdNumber()), + trimming); + + // Look for required attribute + // Find the template name + for (NameValuePair nvp : nvps) { + if (nvp.getName().equals(templateAttName)) { + compElt.setTemplate((String) nvp.getValue()); + } else if (nvp.getName().equals(REQUIRED_ATTRIBUTE)) { + compElt.setRequired(nvp.getValue().toString()); + } else { + // We are going to treat extra attributes on compositions to be + // ui:param values + compElt.setParameter(nvp.getName(), nvp.getValue()); + } + } + + parent.addChildLayoutElement(compElt); + + // See if this is a single tag or not... + TemplateParser parser = reader.getTemplateParser(); + int ch = parser.nextChar(); + if (ch == '/') { + reader.popTag(); // Don't look for end tag + } else { + // Unread the ch we just read + parser.unread(ch); + + // Process child LayoutElements (recurse) + reader.process( + LAYOUT_COMPOSITION_CONTEXT, compElt, + LayoutElementUtil.isLayoutComponentChild(compElt)); + } + + if (trimming) { + // End processing... (trimming == true) + throw new ProcessingCompleteException((LayoutDefinition) parent); + } + } + + + /** + *

    This is the {@link ProcessingContext} for + * {@link LayoutComposition}s.

    + */ + protected static class LayoutCompositionContext extends BaseProcessingContext { + /** + *

    This is called when a special tag is found (<!tagname ...).

    + * + *

    This implementation looks for "define" tags and handles them + * specially. These tags are only valid in this context.

    + */ + public void beginSpecial(ProcessingContextEnvironment env, String content) throws IOException { + if (content.equals("define")) { + DEFINE_PARSER_COMMAND.process(this, env, content); + } else { + super.beginSpecial(env, content); + } + } + } + + + /** + *

    This indicates whether content outside of this tag should be left + * alone or used.

    + */ + private boolean trimming = true; + private String templateAttName = null; + + public static final String REQUIRED_ATTRIBUTE = "required"; + /** + *

    The {@link ProcessingContext} to be used when processing children + * of a {@link LayoutComposition}. This {@link ProcessingContext} may + * have special meaning for + * {@link com.sun.jsftemplating.layout.descriptors.LayoutDefine}s and + * other tags.

    + */ + public static final ProcessingContext LAYOUT_COMPOSITION_CONTEXT = + new LayoutCompositionContext(); + + public static final CustomParserCommand DEFINE_PARSER_COMMAND = + new DefineParserCommand(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/CustomParserCommand.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/CustomParserCommand.java new file mode 100644 index 0000000..1a45219 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/CustomParserCommand.java @@ -0,0 +1,49 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import java.io.IOException; + + +/** + *

    This interface provides a way to process "custom" parser commands. + * These commands are in the format: "<![custom command name] ...". + * They must be registered with the TemplateParser to be recognized. + * See {@link TemplateReader#setCustomParserCommand(String, CustomParserCommand)}.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public interface CustomParserCommand { + + /** + *

    This method processes a "custom" command. These are commands that + * start with a !. When this method receives control, the + * name (i.e. the token after the '!' character) has + * already been read. It is passed via the name + * parameter.

    + * + *

    The {@link ProcessingContext} and + * {@link ProcessingContextEnvironment} are both available.

    + */ + void process(ProcessingContext ctx, ProcessingContextEnvironment env, String name) throws IOException; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/DefineParserCommand.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/DefineParserCommand.java new file mode 100644 index 0000000..326fb2d --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/DefineParserCommand.java @@ -0,0 +1,103 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.layout.ProcessingCompleteException; +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.LayoutDefine; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.util.LayoutElementUtil; + +import java.io.IOException; + + +/** + *

    This {@link CustomParserCommand} handles "composition" statements. + * TBD... + *

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class DefineParserCommand implements CustomParserCommand { + + /** + *

    This method processes a "custom" command. These are commands that + * start with a !. When this method receives control, the + * name (i.e. the token after the '!' character) has + * already been read. It is passed via the name + * parameter.

    + * + *

    The {@link ProcessingContext} and + * {@link ProcessingContextEnvironment} are both available.

    + */ + public void process(ProcessingContext ctx, ProcessingContextEnvironment env, String name) throws IOException { + // Get the reader and parser + TemplateReader reader = env.getReader(); + TemplateParser parser = reader.getTemplateParser(); + + // Skip any white space... + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + + // Get the parent and define name + LayoutElement parent = env.getParent(); + String id = (String) parser.getNVP(NAME_ATTRIBUTE, true).getValue(); + + // Create new LayoutDefine + LayoutDefine compElt = new LayoutDefine(parent, id); + parent.addChildLayoutElement(compElt); + + // Skip any white space or extra junk... + String theRest = parser.readUntil('>', true).trim(); + if (theRest.endsWith("/")) { + reader.popTag(); // Don't look for end tag + } else { + // Process child LayoutElements (recurse) + reader.process( + LAYOUT_DEFINE_CONTEXT, compElt, + LayoutElementUtil.isLayoutComponentChild(compElt)); + } + } + + + /** + *

    This is the {@link ProcessingContext} for + * {@link LayoutDefine}s.

    + */ + protected static class LayoutDefineContext extends BaseProcessingContext { + } + + /** + *

    A String containing "template". This is the attribute name of the + * template file to use in the {@link LayoutDefine}.

    + */ + public static final String NAME_ATTRIBUTE = "name"; + + /** + *

    The {@link ProcessingContext} to be used when processing children + * of a {@link LayoutDefine}. This {@link ProcessingContext} may + * have special meaning for {@link LayoutDefine}s and other tags.

    + */ + public static final ProcessingContext LAYOUT_DEFINE_CONTEXT = + new LayoutDefineContext(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/EventParserCommand.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/EventParserCommand.java new file mode 100644 index 0000000..574b703 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/EventParserCommand.java @@ -0,0 +1,406 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition; +import com.sun.jsftemplating.layout.descriptors.handler.OutputTypeManager; +import com.sun.jsftemplating.util.LayoutElementUtil; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Stack; + + +/** + *

    This {@link CustomParserCommand} implementation processes handlers for + * an event.

    + */ +public class EventParserCommand implements CustomParserCommand { + /** + *

    This method processes a "custom" command. These are commands that + * start with a !. When this method receives control, the + * name (i.e. the token after the '!' character) has + * already been read. It is passed via the name + * parameter.

    + * + *

    This implementation processes events and their handlers. 2 + * syntaxes are supported:

    + * + *
    • <event type="beforeCreate">handler1(input="foo" output="bar"); ... </event>
    • + *
    • <!beforeCreate handler1(input="foo" output="bar"); ... />
    + * + *

    The first format should be preferred.

    + * + *

    The {@link ProcessingContext} and + * {@link ProcessingContextEnvironment} are both available.

    + */ + public void process(ProcessingContext ctx, ProcessingContextEnvironment env, String eventName) throws IOException { + Handler handler = null; + List handlers = new ArrayList(); + TemplateReader reader = env.getReader(); + TemplateParser parser = reader.getTemplateParser(); + Handler parentHandler = null; + Stack handlerStack = new Stack(); + LayoutElement parent = env.getParent(); + + // Skip whitespace... + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + int ch = -1; + + // We now support 2 syntaxes: + // [handlers] + // + // If "eventName" is event, look for type and the closing '>' before + // trying to parse the handlers. + boolean useBodyContent = false; + boolean createHandlerDefinitionOnLayoutDefinition = false; + if (eventName.equals("handler")) { + // We have a tag... + createHandlerDefinitionOnLayoutDefinition = true; + useBodyContent = true; + + // Read type="...", no other options are supported at this time + NameValuePair nvp = parser.getNVP(null); + if (!nvp.getName().equals("id")) { + throw new SyntaxException( + "When defining and event, you must supply the event type! " + + "Found \"...event " + nvp.getName() + "\" instead."); + } + eventName = nvp.getValue().toString(); + + // Ensure the next character is '>' + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + ch = parser.nextChar(); + if (ch != '>') { + throw new SyntaxException( + "Syntax error in event definition, found: '...handler id=\"" + + eventName + "\" " + ((char) ch) + + "\'. Expected closing '>' for opening handler element."); + } + + // Get ready to read the handlers now... + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + ch = parser.nextChar(); + } else if (eventName.equals("event")) { + // We have the new syntax... + useBodyContent = true; + + // Read type="...", no other options are supported at this time + NameValuePair nvp = parser.getNVP(null); + if (!nvp.getName().equals("type")) { + throw new SyntaxException( + "When defining and event, you must supply the event type! " + + "Found \"...event " + nvp.getName() + "\" instead."); + } + eventName = nvp.getValue().toString(); + + // Ensure the next character is '>' + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + ch = parser.nextChar(); + if (ch != '>') { + throw new SyntaxException( + "Syntax error in event definition, found: '...event type=\"" + + eventName + "\" " + ((char) ch) + + "\'. Expected closing '>' for opening event element."); + } + + // Get ready to read the handlers now... + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + ch = parser.nextChar(); + } else { + // Make sure to read the first char for the old syntax... + ch = parser.nextChar(); + } + + // Read the Handler(s)... + while (ch != -1) { + if (useBodyContent) { + // If we're using the new format.... check for "" + if (ch == '<') { + // Just unread the '<', framework will validate the rest + parser.unread('<'); + break; + } + } else { + if ((ch == '/') || (ch == '>')) { + // We found the end in the case where the handlers are + // inside the tag (old syntax). + break; + } + } + // Check for {}'s + if ((ch == LEFT_CURLY) || (ch == RIGHT_CURLY)) { + if (ch == LEFT_CURLY) { + // We are defining child handlers + handlerStack.push(parentHandler); + parentHandler = handler; + } else { + // We are DONE defining child handlers + if (handlerStack.empty()) { + throw new SyntaxException("Encountered unmatched '" + + RIGHT_CURLY + "' when parsing handlers for '" + + eventName + "' event."); + } + parentHandler = handlerStack.pop(); + } + + // ';' or ',' characters may appear between handlers + parser.skipCommentsAndWhiteSpace( + TemplateParser.SIMPLE_WHITE_SPACE + ",;"); + + // We need to "continue" b/c we need to check next ch again + ch = parser.nextChar(); + continue; + } + + // Get Handler ID / Definition + parser.unread(ch); + + // Read a Handler + handler = readHandler(parser, eventName, parent); + + // Add the handler to the appropriate place + if (parentHandler == null) { + handlers.add(handler); + } else { + parentHandler.addChildHandler(handler); + } + + // Look at the next character... + ch = parser.nextChar(); + } + if (ch == -1) { + // Make sure we didn't get to the end of the file + throw new SyntaxException("Unexpected EOF encountered while " + + "parsing handlers for event '" + eventName + "'!"); + } + + // Do some checks to make sure everything is good... + if (!handlerStack.empty()) { + throw new SyntaxException("Unmatched '" + LEFT_CURLY + + "' when parsing handlers for '" + eventName + + "' event."); + } + if (!useBodyContent) { + // Additional checks for old syntax... + if (ch == '>') { + throw new SyntaxException("Handlers for event '" + eventName + + "' did not end with '/>' but instead ended with '>'!"); + } + if (ch == '/') { + // Make sure we have a "/>"... + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + ch = parser.nextChar(); + if (ch != '>') { + throw new SyntaxException("Expected '/>' a end of '" + + eventName + "' event. But found '/" + + (char) ch + "'."); + } + reader.popTag(); // Get rid of this event tag from the Stack + ctx.endSpecial(env, eventName); + } + } else { + // We need to recurse in order for the end-tag code to properly + // close out the context and make everything run correctly... + // Process child LayoutElements (should be none) + reader.process(EVENT_PROCESSING_CONTEXT, parent, + LayoutElementUtil.isLayoutComponentChild(parent)); + } + + // Set the Handlers on the parent... + if (createHandlerDefinitionOnLayoutDefinition) { + HandlerDefinition def = new HandlerDefinition(eventName); + def.setChildHandlers(handlers); + parent.getLayoutDefinition().setHandlerDefinition(eventName, def); + } else { + parent.setHandlers(eventName, handlers); + } + } + + /** + *

    This method parses and creates an individual + * Handler.

    + */ + private Handler readHandler(TemplateParser parser, String eventName, LayoutElement parent) throws IOException { + String target = null; + String defVal = null; + NameValuePair nvp = null; + HandlerDefinition def = null; + + String handlerId = parser.readToken(); + // Check locally defined Handler + def = parent.getLayoutDefinition().getHandlerDefinition(handlerId); + if (def == null) { + // Check globally defined Handler + def = LayoutDefinitionManager.getGlobalHandlerDefinition(handlerId); + if (def == null) { + throw new SyntaxException("Handler '" + handlerId + + "' in event '" + eventName + "' is not declared! " + + "Ensure the '@Handler' annotation has been defined " + + "on the handler Java method, that it has been " + + "compiled with the annotation processing tool, and " + + "that the resulting" + + " 'META-INF/jsftemplating/Handler.map' is located " + + "in your classpath (you may need to do a clean " + + "build)."); + } + } + + // Create a Handler + Handler handler = new Handler(def); + + // Get the default name + Map inputs = def.getInputDefs(); +// FIXME: Allow for HandlerDefs to declare their default input + if (inputs.size() == 1) { + defVal = inputs.keySet().toArray()[0].toString(); + } + + // Get the outputs so we can see what outputs have been declared + Map outputs = def.getOutputDefs(); + + // Ensure we have an opening parenthesis + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + int ch = parser.nextChar(); + if (ch != '(') { + throw new SyntaxException("While processing '<!" + eventName + + "...' the handler '" + handlerId + + "' was missing the '(' character!"); + } + + // Move to the first char inside the parenthesis + parser.skipWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + ch = parser.nextChar(); + + // We should not ignore '#' characters for 'if' (Issue #5) + if ((ch != '#') || !handlerId.equals(IF_HANDLER)) { + parser.unread(ch); + parser.skipCommentsAndWhiteSpace(""); // Already skipped white + ch = parser.nextChar(); + } + + // Allow if() handlers to be more flexible... + if (handlerId.equals(IF_HANDLER) + && (ch != '\'') && (ch != '"') && (ch != 'c')) { +// FIXME: check for "condition", otherwise expressions starting with 'c' will +// FIXME: not parse correctly + // We have an if() w/o a condition="" && w/o quotes... + // Take the entire value inside the ()'s to be the expression + parser.unread(ch); + handler.setCondition(parser.readUntil(')', false).trim()); + ch = ')'; + } + + // Read NVP(s)... + while ((ch != -1) && (ch != ')')) { + // Read NVP + parser.unread(ch); + try { + nvp = parser.getNVP(defVal); + } catch (SyntaxException ex) { + throw new SyntaxException("Unable to process handler '" + + handlerId + "'!", ex); + } + parser.skipCommentsAndWhiteSpace( + TemplateParser.SIMPLE_WHITE_SPACE + ",;"); + ch = parser.nextChar(); + + // Store the NVP.. + target = nvp.getTarget(); + if (target != null) { + // "old-style" OutputMapping (key=>$attribute{value}) + // NOTE: 'value' must be a String for an OutputMapping + handler.setOutputMapping( + nvp.getName(), nvp.getValue().toString(), target); + } else { + // First check for special input value (condition) + String name = nvp.getName(); + if (name.equals(CONDITION_ATTRIBUTE) + && ((inputs.get(CONDITION_ATTRIBUTE) == null) + || (handlerId.equals(IF_HANDLER)))) { + // We have a Handler condition, set it + handler.setCondition(nvp.getValue().toString()); + } else { + // We still don't know if this is an input, output, or both + // (EL is now supported as an output mapping: out="#{el}") + boolean validIO = false; + // We also check to see if the "old" output mapping was + // used and DO NOT override it if it was. This is useful + // if there are cases where an input and output share a + // name and the user does not fix this... the old syntax + // can reliably declare an output without a namespace + // problem. + if (outputs.containsKey(name) && (handler.getOutputValue(name) == null)) { + // We have an Output... use 2 arg method for this + // syntax (expects EL, or uses simple String for a + // request attribute). + handler.setOutputMapping( + name, nvp.getValue().toString(), + OutputTypeManager.EL_TYPE); + validIO = true; + } + // Don't do "else" b/c it may be BOTH an input AND output + if (inputs.containsKey(name)) { + // We have an Input + handler.setInputValue(name, nvp.getValue()); + validIO = true; + } + if (!validIO) { + throw new IllegalArgumentException( + "Input or output named \"" + name + + "\" was declared for handler \"" + + handlerId + "\" in event \"" + eventName + + "\", however, no such input or output exists!"); + } + } + } + } + + // ';' or ',' characters may appear between handlers + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE + ",;"); + + // Return the Handler + return handler; + } + + /** + *

    This is the {@link ProcessingContext} for events. Currently does + * nothing.

    + */ + protected static class EventProcessingContext extends BaseProcessingContext { + } + + public static final String IF_HANDLER = "if"; + public static final String CONDITION_ATTRIBUTE = "condition"; + public static final ProcessingContext EVENT_PROCESSING_CONTEXT = + new EventProcessingContext(); + + public static final char LEFT_CURLY = '{'; + public static final char RIGHT_CURLY = '}'; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/InsertParserCommand.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/InsertParserCommand.java new file mode 100644 index 0000000..045efba --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/InsertParserCommand.java @@ -0,0 +1,104 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.layout.ProcessingCompleteException; +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.LayoutInsert; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.util.LayoutElementUtil; + +import java.io.IOException; + + +/** + *

    This {@link CustomParserCommand} handles "insert" statements. + * TBD... + *

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class InsertParserCommand implements CustomParserCommand { + + /** + *

    This method processes a "custom" command. These are commands that + * start with a !. When this method receives control, the + * name (i.e. the token after the '!' character) has + * already been read. It is passed via the name + * parameter.

    + * + *

    The {@link ProcessingContext} and + * {@link ProcessingContextEnvironment} are both available.

    + */ + public void process(ProcessingContext ctx, ProcessingContextEnvironment env, String name) throws IOException { + // Get the reader and parser + TemplateReader reader = env.getReader(); + TemplateParser parser = reader.getTemplateParser(); + + // Skip any white space... + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + + // Get the parent and insert name + LayoutElement parent = env.getParent(); + String id = (String) parser.getNVP(NAME_ATTRIBUTE, true).getValue(); + + // Create new LayoutInsert + LayoutInsert compElt = new LayoutInsert(parent, id); + compElt.setName(id); + parent.addChildLayoutElement(compElt); + + // Skip any white space or extra junk... + String theRest = parser.readUntil('>', true).trim(); + if (theRest.endsWith("/")) { + reader.popTag(); // Don't look for end tag + } else { + // Process child LayoutElements (recurse) + reader.process( + LAYOUT_INSERT_CONTEXT, compElt, + LayoutElementUtil.isLayoutComponentChild(compElt)); + } + } + + + /** + *

    This is the {@link ProcessingContext} for + * {@link LayoutInsert}s.

    + */ + protected static class LayoutInsertContext extends BaseProcessingContext { + } + + /** + *

    A String containing "template". This is the attribute name of the + * template file to use in the {@link LayoutInsert}.

    + */ + public static final String NAME_ATTRIBUTE = "name"; + + /** + *

    The {@link ProcessingContext} to be used when processing children + * of a {@link LayoutInsert}. This {@link ProcessingContext} may + * have special meaning for {@link LayoutInsert}s and other tags.

    + */ + public static final ProcessingContext LAYOUT_INSERT_CONTEXT = + new LayoutInsertContext(); +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/NameValuePair.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/NameValuePair.java new file mode 100644 index 0000000..886925c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/NameValuePair.java @@ -0,0 +1,86 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + + +/** + *

    This class is used to represent NVP information. This information + * consists of 2 or 3 parts. If this is a simple Name Value Pair, it will + * contain a name and a value. If it is an NVP + * that is used to map a return value, then it also contains a + * target as well (which should be set to "session" or + * "attribute"). name and target contain + * String values. The value property contains + * an Object value because it may be a String, + * java.util.List, or an array[].

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class NameValuePair { + public NameValuePair(String name, Object value, String target) { + _name = name; + _value = value; + _target = target; + } + + /** + *

    Name accessor.

    + */ + public String getName() { + return _name; + } + + /** + *

    Value accessor.

    + */ + public Object getValue() { + return _value; + } + + /** + *

    Target accessor. If this value is non-null it can be assumed that + * this is an output mapping. However, if it is null it cannot be + * assumed to be an input mapping -- it may still be an output mapping + * or an in-out mapping which uses EL. Valid values for this are + * currently: (null), "pageSession", "attribute", or "session" (this + * list may be expanded in the future).

    + */ + public String getTarget() { + return _target; + } + + /** + *

    Customized to reconstruct the NVP.

    + */ + public String toString() { + if (getTarget() == null) { + return getName() + "=\"" + getValue() + '"'; + } else { + return getName() + "=>$" + getTarget() + '{' + getValue() + '}'; + } + } + + private String _name = null; + private Object _value = null; + private String _target = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/NamespaceParserCommand.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/NamespaceParserCommand.java new file mode 100644 index 0000000..390bae9 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/NamespaceParserCommand.java @@ -0,0 +1,103 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.layout.ProcessingCompleteException; +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.LayoutComposition; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.util.LayoutElementUtil; + +import java.io.IOException; +import java.util.List; + + +/** + *

    This {@link CustomParserCommand} handles "namespace" declarations. The + * format of this command should be:

    + * + *
    • + * <!namespace "longname"="shortname" /> + *
    + * + *

    For example:

    + * + *
    • + * <!namespace "http://java.sun.com/mojarra/scales"="sc" /> + *
    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class NamespaceParserCommand implements CustomParserCommand { + + /** + *

    Constructor.

    + */ + public NamespaceParserCommand() { + } + + /** + *

    This method processes a "custom" command. These are commands that + * start with a !. When this method receives control, the + * name (i.e. the token after the '!' character) has + * already been read. It is passed via the name + * parameter.

    + * + *

    The {@link ProcessingContext} and + * {@link ProcessingContextEnvironment} are both available.

    + */ + public void process(ProcessingContext ctx, ProcessingContextEnvironment env, String name) throws IOException { + // Get the reader + TemplateReader reader = env.getReader(); + TemplateParser parser = reader.getTemplateParser(); + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + int ch = parser.nextChar(); + if ((ch == '>') || (ch == '/')) { + // Nothing specified, throw exception! + throw new IllegalArgumentException( + "Found an empty \"\" delcaration! The long and" + + " short namespace names must be provided."); + } + parser.unread(ch); + + // Next get the next NVP... + NameValuePair nvp = parser.getNVP(null, true); + + // Make sure we read the WS after the data... + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + + // Now make sure this is an end tag... + ch = parser.nextChar(); + int ch2 = parser.nextChar(); + if ((ch != '/') || (ch2 != '>')) { + throw new IllegalArgumentException( + "[\"!"); + } + reader.popTag(); // Don't look for end tag + + // Save the mapping... + reader.setNamespace(nvp.getName(), nvp.getValue().toString()); + } +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/ProcessingContext.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/ProcessingContext.java new file mode 100644 index 0000000..b0a814c --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/ProcessingContext.java @@ -0,0 +1,88 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import java.io.IOException; + +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + *

    This interface defines the operations that may be acted upon while + * a "template" document is traversed. The intent is that this + * interface may be implemented by the different "processing contexts" + * which occur throught the template file. This provides the + * opportunity for context sensitive syntax in an easy to provide + * way.

    + * + *

    While the standard ProcessingContext instances are + * likely to be sufficient, there may be cases where a custom + * ProcessingContext may be needed to process the + * children of a {@link CustomParserCommand}. This may be done by + * implementing this interface, or extending one of the existing + * implementations. Typically this object is used by passing it to + * the {@link TemplateReader#process(ProcessingContext, LayoutElement, boolean)} + * method -- this method will delegate actions back to the given + * ProcessingContext.

    + */ +public interface ProcessingContext { + + /** + *

    This is called when a component tag is found (<tagname ...).

    + */ + void beginComponent(ProcessingContextEnvironment env, String content) throws IOException; + + /** + *

    This is called when an end component tag is found (</tagname + * ... or <tagname ... />).

    + */ + void endComponent(ProcessingContextEnvironment env, String content) throws IOException; + + /** + *

    This is called when a special tag is found (<!tagname ...).

    + */ + void beginSpecial(ProcessingContextEnvironment env, String content) throws IOException; + + /** + *

    This is called when a special end tag is found (</tagname ... + * or <!tagname ... />).

    + */ + void endSpecial(ProcessingContextEnvironment env, String content) throws IOException; + + /** + *

    This is called when static text is found (").

    + */ + void staticText(ProcessingContextEnvironment env, String content) throws IOException; + + /** + *

    This is called when escaped static text is found ('). The + * difference between this and staticText is that HTML is expected to + * be escaped so the browser does not parse it.

    + */ + void escapedStaticText(ProcessingContextEnvironment env, String content) throws IOException; + + /** + *

    This method is invoked when nothing else matches.

    + */ + void handleDefault(ProcessingContextEnvironment env, String content) throws IOException; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/ProcessingContextEnvironment.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/ProcessingContextEnvironment.java new file mode 100644 index 0000000..c905c95 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/ProcessingContextEnvironment.java @@ -0,0 +1,98 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.layout.descriptors.LayoutElement; + + +/** + *

    This class hold environmental information needed while a parsing. This + * information is specific to the nested level that is currently being + * processed. This is unlike the {@link ProcessingContext} + * which is related to the "type" of element that is being processed. Or + * said another way, the {@link ProcessingContext} + * specifies how / what sub-elements are to be processed based on the + * context; this class provides the "where" information for that + * processing. Another difference is this class is stateful, the + * {@link ProcessingContext} has stateless methods that + * parse specific portions of the document.

    + * + * @see TemplateReader + * @see ProcessingContext + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class ProcessingContextEnvironment { + + /** + *

    Constructor.

    + */ + public ProcessingContextEnvironment(TemplateReader reader, LayoutElement parent, boolean nested) { + _reader = reader; + _parent = parent; + _nested = nested; + } + + /** + * @return The TemplateReader instance. + */ + public TemplateReader getReader() { + return _reader; + } + + /** + * @return true if nested in a LayoutComponent. + */ + public boolean isNested() { + return _nested; + } + + /** + * @return The parent {@link LayoutElement}. + */ + public LayoutElement getParent() { + return _parent; + } + + /** + *

    This method marks the current {@link ProcessingContext} as + * complete.

    + */ + public void setFinished(boolean finished) { + _finished = finished; + } + + /** + *

    This method indicates if the current {@link ProcessingContext} + * is still valid.

    + */ + public boolean isFinished() { + return _finished; + } + + boolean _finished = false; + boolean _special = false; + boolean _nested = false; + LayoutElement _parent = null; + TemplateReader _reader = null; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/TemplateLayoutDefinitionManager.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/TemplateLayoutDefinitionManager.java new file mode 100644 index 0000000..cb39ca1 --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/TemplateLayoutDefinitionManager.java @@ -0,0 +1,211 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.annotation.FormatDefinition; +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.util.FileUtil; + +import java.io.IOException; +import java.net.URL; + +import javax.faces.context.FacesContext; + + +/** + *

    This class is a concrete implmentation of the abstract class + * {@link LayoutDefinitionManager}. It obtains {@link LayoutDefinition} + * objects by interpreting the key passed to + * {@link #getLayoutDefinition(String)} as a path to a template file + * describing the {@link LayoutDefinition}. It will first attempt to + * resolve this path from the document root of the ServletContext or + * PortletCotnext. If that fails, it will attempt to use the Classloader + * to resolve it.

    + * + *

    This class is a singleton.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +@FormatDefinition +public class TemplateLayoutDefinitionManager extends LayoutDefinitionManager { + + /** + *

    Constructor.

    + */ + protected TemplateLayoutDefinitionManager() { + super(); + } + + /** + *

    This method returns an instance of this LayoutDefinitionManager. + * The object returned is a singleton (only 1 instance will be + * created per application).

    + * + * @return TemplateLayoutDefinitionManager instance + */ + public static LayoutDefinitionManager getInstance() { + return getInstance(FacesContext.getCurrentInstance()); + } + + /** + *

    This method provides access to the application-scoped instance + * of the TemplateLayoutDefinitionManager.

    + * + * @param ctx The FacesContext (may be null). + */ + public static LayoutDefinitionManager getInstance(FacesContext ctx) { + if (ctx == null) { + ctx = FacesContext.getCurrentInstance(); + } + TemplateLayoutDefinitionManager instance = null; + if (ctx != null) { + instance = (TemplateLayoutDefinitionManager) + ctx.getExternalContext().getApplicationMap().get(TLDM_INSTANCE); + } + if (instance == null) { + instance = new TemplateLayoutDefinitionManager(); + if (ctx != null) { + ctx.getExternalContext().getApplicationMap().put( + TLDM_INSTANCE, instance); + } + } + return instance; + } + + /** + *

    This method uses the key to determine if this + * {@link LayoutDefinitionManager} is responsible for handling the + * key.

    + * + *

    The template format is very flexible which makes it difficult to + * detect this vs. another format. For this reason, it is suggested + * that this format be attempted last (or at least after more + * detectable formats).

    + * + *

    This method checks the first character that is not a comment or + * whitespace (according to the TemplateParser). If this first + * character is a single quote or double quote it return + * true. If it is a "<" character, it looks to see + * if it starts with "<?" or "<!DOCTYPE". If it does start + * that way, it returns false; otherwise it returns + * true. If any other character is found or an + * exception is thrown, it will return false.

    + */ + public boolean accepts(String key) { + URL url = null; + try { + url = FileUtil.searchForFile(key, ".jsf"); + } catch (IOException ex) { + // Ignore this b/c we're just trying to detect if we're the right + // LDM... if we're here, probably we're not. + } + if (url == null) { + return false; + } + + // Use the TemplateParser to help us read the file to see if it is a + // valid XML-format file + TemplateParser parser = new TemplateParser(url); + try { + parser.open(); + parser.skipCommentsAndWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + int ch = parser.nextChar(); + switch (ch) { + case '<': + ch = parser.nextChar(); + if (ch == '?') { + // XML Documents often start with "", '?' is + // not valid after '<' in this format + return false; + } + if (ch == '!') { + String token = parser.readToken(); + if (token.equalsIgnoreCase("doctype")) { + // This method is responsible for finding the requested + * {@link LayoutDefinition} for the given key.

    + * + * @param key Key identifying the desired {@link LayoutDefinition}. + * + * @return The requested {@link LayoutDefinition}. + */ + public LayoutDefinition getLayoutDefinition(String key) throws LayoutDefinitionException { + // Make sure we found the url + URL url = null; + try { + url = FileUtil.searchForFile(key, ".jsf"); + } catch (IOException ex) { + throw new LayoutDefinitionException( + "Unable to locate '" + key + "'", ex); + } + if (url == null) { + throw new LayoutDefinitionException( + "Unable to locate '" + key + "'"); + } + + // Read the template file + LayoutDefinition ld = null; + try { + ld = new TemplateReader(key, url).read(); + } catch (IOException ex) { + throw new LayoutDefinitionException( + "Unable to process '" + url.toString() + "'.", ex); + } + + // Dispatch "initPage" handlers + ld.dispatchInitPageHandlers(FacesContext.getCurrentInstance(), ld); + + // Return the LayoutDefinition + return ld; + } + + /** + *

    Application scope key for an instance of this class.

    + */ + private static final String TLDM_INSTANCE = "__jsft_TemplateLDM"; +} diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/TemplateParser.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/TemplateParser.java new file mode 100644 index 0000000..9d87f3b --- /dev/null +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/template/TemplateParser.java @@ -0,0 +1,791 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import com.sun.jsftemplating.layout.SyntaxException; +import com.sun.jsftemplating.layout.descriptors.handler.OutputTypeManager; +import com.sun.jsftemplating.util.IncludeInputStream; +import com.sun.jsftemplating.util.LogUtil; + + +/** + *

    This class is responsible for the actual parsing of a template.

    + * + *

    This class is intended to read the template one time. Often it may be + * useful to cache the result as it would be inefficient to reread a + * template multiple times. Templates that are generated from this class + * are intended to be static and safe to share. However, this class + * itself is not thread safe.

    + * + * @author Ken Paulsen (ken.paulsen@sun.com) + */ +public class TemplateParser { + + /** + *

    Constructor.

    + * + * @param url URL pointing to the template. + */ + public TemplateParser(URL url) { + _url = url; + } + + /** + *

    Constructor which accepts a InputStream.

    + * + * @param stream InputStream for the template. + */ + public TemplateParser(InputStream stream) { + _inputStream = stream; + } + + /** + *

    Accessor for the URL.

    + */ + public URL getURL() { + return _url; + } + + /** + *

    Accessor for the InputStream. This either comes from + * the supplied URL, or simply from the supplied + * InputStream.

    + */ + public InputStream getInputStream() throws IOException { + if ((_inputStream == null) && (_url != null)) { + _inputStream = getURL().openStream(); + } + return _inputStream; + } + + /** + *

    The init method opens the given URL pointing to a + * template and prepares to parses it.

    + * + * @throws IOException + */ + public void open() throws IOException { + if (_reader != null) { + // Generally this should not happen, but just in case... start over + close(); + } + +// FIXME: It is possible while evaluating the file an #include may need to log a message to the screen! Provide a callback mechanism to do this in a Template-specific way + // Create the reader from the stream + _reader = new BufferedReader( + new InputStreamReader( + new IncludeInputStream( + new BufferedInputStream(getInputStream())))); + + // Initialize the queue we will use to push values back + _stack = new Stack(); + } + + /** + *

    This method closes the stream if it is open. It doesn't throw an + * exception, instead it logs any exceptions at the CONFIG level.

    + */ + public void close() { + try { + if (_reader != null) { + _reader.close(); + } + } catch (Exception ex) { + if (LogUtil.configEnabled(this)) { + LogUtil.config("Exception while closing stream for url: '" + + getURL() + "'.", ex); + } + } + } + + /** + *

    This method returns the next character.

    + */ + public int nextChar() throws IOException { + if (!_stack.empty()) { + // We have values in the queue + return _stack.pop().charValue(); + } + return _reader.read(); + } + + /** + *

    This method pushes a character on the read queue so that it will + * be read next.

    + */ + public void unread(int ch) { + _stack.push(new Character((char) ch)); + } + + /** + *

    This method reads a "Name Value Pair" from the stream. For the + * purposes of this method, a "Name Value Pair" may look like like one + * of these formats:

    + * + * + *
    • keyName="keyValue"
    • + *
    • keyName='keyValue'
    • + *
    • "keyValue" (only if defName is supplied)
    • + *
    • 'keyValue' (only if defName is supplied)
    • + *
    • keyName=>$attribute{attributeKey}
    • + *
    • keyName=>$session{sessionKey}
    + *
  • keyName=>$page{pageSessionKey}
  • + *
  • keyName=>$pageSession{pageSessionKey}
  • + *
    + * + *

    In the first two formats, keyName must consist of + * letters, numbers, or the underscore '_' character. + * keyValue must be wrapped in single or double quotes. + * The backslash '\' character may be used to escape characters, this + * may be useful if a backslash, single, or double quote exists in + * the string.

    + * + *

    The last four formats are only used for mapping return values. + * This is necessary when a handler returns a value so that the value + * can be stored somewhere. keyName in these cases is + * the name of the return value to map. The value after the dollar + * '$' character (which is either "attribute", "page", "pageSession", + * or "session") specifies the type of storage the value should be + * saved. The value inside the curly braces "{}" specifies the key + * that should be used when saving the value as a request, page, or + * session attribute.

    + * + *

    The return value is of type {@link NameValuePair}. This object + * contains the necessary information to interpret this NVP.

    + * + * @param defName The default name to use if ommitted. If + * null, no default will be used -- a + * {@link SyntaxException} will be generated. + * + * @return A {@link NameValuePair} object containing the NVP info. + */ + public NameValuePair getNVP(String defName) throws IOException { + return getNVP(defName, true); + } + + /** + *

    This method behaves the same as {@link #getNVP(String)}, however, + * it adds the ability to make quotes around the value optional. This + * is done by passing in false for + * requireQuotes. This is used by some special commands + * which only take a single argument with no property name. In this + * case, the value will be read until a '>' is encountered (if + * "/>" is encountered, it will stop before the '/').

    + * + *

    Also, in cases where quotes are optional, output NVPs will not be + * allowed. The rationale is that the "=>$...{...}" syntax did + * not require quotes already, and use cases which allow for omitting + * quotes do not use output mappings.

    + * + * @param defName The default name to use if ommitted. If + * null, no default will be used -- a + * {@link SyntaxException} will be generated. + * + * @param requireQuotes Flag indicating whether enforce the use of + * quotes or not. + * + * @return A {@link NameValuePair} object containing the NVP info. + * + * @throws {@link SyntaxException} if the syntax is not correct. + */ + public NameValuePair getNVP(String defName, boolean requireQuotes) throws IOException { + return getNVP(defName, requireQuotes, "_."); + } + + /** + *

    This method behaves the same as {@link #getNVP(String, boolean)}, + * however, it adds the ability to specify the valid characters which + * may appear in the parameter name (via otherChars).

    + * + * @param defName The default name to use if ommitted. If + * null, no default will be used -- a + * {@link SyntaxException} will be generated. + * + * @param requireQuotes Flag indicating whether enforce the use of + * quotes or not. + * + * @param otherChars Other valid characters. + * + * @return A {@link NameValuePair} object containing the NVP info. + * + * @throws {@link SyntaxException} if the syntax is not correct. + */ + public NameValuePair getNVP(String defName, boolean requireQuotes, String otherChars) throws IOException { + // Read the name + String name = readToken(otherChars); + Object value = null; + + // Check for empty name + if ((name.length() == 0) && (defName != null)) { + name = defName; // Use default name + unread('='); // Add '=' character + } + + // Skip White Space + skipCommentsAndWhiteSpace(SIMPLE_WHITE_SPACE); + + // Ensure next character is '=' + int next = nextChar(); + if ((next != '=') && (next != ':')) { + if (!requireQuotes && !name.equals(defName)) { + // This is the case where there is no property name and no + // quotes, the whole string is the value. + value = name; + name = defName; + // Add a flag to ensure the next switch goes to the "default" case + unread(next); + unread('f'); + } else { + throw new SyntaxException( + "'=' or ':' missing for Name Value Pair: '" + name + "'!"); + } + } + + // Skip whitespace... + skipCommentsAndWhiteSpace(SIMPLE_WHITE_SPACE); + + // Check for '>' character (means we're mapping an output value) + String target = null; + int endingChar = -1; + next = nextChar(); + switch (next) { + case '>': + if (!requireQuotes) { + // This means output mappings are not allowed, this must + // be the end of the input (meaning there was no input + // since we're at the beginning also) + unread(next); + value = ""; + break; + } + + // We are mapping an output value, this should look like: + // keyName => $attribute{attKey} + // keyName => $application{appKey} + // keyName => $session{sessionKey} + // keyName => $pageSession{pageSessionKey} + + // First skip any whitespace after the '>' + skipCommentsAndWhiteSpace(SIMPLE_WHITE_SPACE); + + // Next Make sure we have a '$' character + next = nextChar(); + if (next != '$') { + throw new SyntaxException( + "'$' missing for Name Value Pair named: '" + name + + "=>'! This NVP appears to be a mapping expression, " + + "therefor requires a format similar to:\n\t" + name + + " => $attribute{attKey}\nor:\n\t" + name + + " => $application{applicationKey}\nor:\n\t" + name + + " => $session{sessionKey}\nor:\n\t" + name + + " => $pageSession{pageSessionKey}"); + } + + // Next look for valid type... + target = readToken(); + OutputTypeManager otm = OutputTypeManager.getInstance(); + if (otm.getOutputType(null, target) == null) { + throw new SyntaxException( + "Invalid OutputType ('" + target + "') for Name Value " + + "Pair named: '" + name + "=>$" + target + "{...}'! " + + "This NVP appears to be a mapping expression, " + + "therefor requires a format similar to:\n\t" + name + + " => $attribute{attKey}\nor:\n\t" + name + + " => $application{applicationKey}\nor:\n\t" + name + + " => $session{sessionKey}\nor:\n\t" + name + + " => $pageSession{pageSessionKey}"); + } + + // Skip whitespace again... + skipCommentsAndWhiteSpace(SIMPLE_WHITE_SPACE); + + // Now look for '{' + next = nextChar(); + if (next != '{') { + throw new SyntaxException( + "'{' missing for Name Value Pair: '" + name + + "=>$" + target + + "'! The format must resemble the following:\n\t" + + name + " => $" + target + "{key}"); + } + endingChar = '}'; + break; + case '{': + // NVP w/ a List as its value + value = parseList('}'); + break; + case '[': + // NVP w/ an array as its value + value = parseList(']').toArray(); + break; + case '"': + case '\'': + // Regular NVP... + // Set the ending character to the same type of quote + endingChar = next; + break; + case 'f': + if ((value != null) && (value.toString().length() > 0)) { + // We have the case where the whole string is the value + // Get the next character so we can fall through w/ it + // to the default case + next = nextChar(); + } + // Don't break here, fall through... + default: + // See if we require quotes around the value... + if (!requireQuotes) { + unread(next); // Include "next" when getting the value + // Read the value until '>' + String strVal = readUntil('>', true); + + // Unread the '>' + unread('>'); + + // See if we also need put back a '/'... + if (strVal.endsWith("/")) { + // Remove the '/' and place back in the read buffer + strVal = strVal.substring(0, strVal.length() - 1).trim(); + unread('/'); + } + value = (value == null) ? strVal : (value.toString() + strVal); + break; + } + + // This isn't legal, throw an exception + throw new SyntaxException("Name Value Pair named '" + + name + "' is missing single or double quotes enclosing " + + "its value. It must follow one of these formats:\n\t" + + name + "=\"value\"\nor:\n\t" + name + "='value'"); + } + + // Read the value + if (endingChar != -1) { + value = readUntil(endingChar, false); + } + + // Create the NVP object and return it + return new NameValuePair(name, value, target); + } + + /** + *

    This method processes lists of String values in the format:

    + * + *

    "value1", "value2", ...}

    + * + *

    The content inside the Strings can be anything. The double quotes + * can also be single quotes. The separators can be spaces, tabs, new + * lines, commas, semi-colons, or colons. The terminating character + * is whatever is passed in for endChar (shown as '}' + * above).

    + */ + protected List parseList(int endChar) throws IOException { + List list = new ArrayList(); + skipCommentsAndWhiteSpace(SIMPLE_WHITE_SPACE); + int next = nextChar(); + while (next != endChar) { + // We should start w/ a single or double quote + if ((next != '\'') && (next != '"')) { + throw new IllegalArgumentException( + "A List or array is missing a single or double quotes " + + "enclosing one or more of its values. It must " + + "follow:\n\tname={\"value\", ...}\nor:\n\tname={'value'," + + "...}\n\n[]'s may be used in place of {}'s to specify " + + "an array instead of a List."); + } + + // Read everything inside the quotes + list.add(readUntil(next, false)); + + // Skip white space (including the seperators ",:;"); + skipCommentsAndWhiteSpace(SIMPLE_WHITE_SPACE + ",:;"); + next = nextChar(); + } + return list; + } + + /** + *

    This method reads while the stream contains letters, numbers, the + * colon character ':', a dot '.', or the underscore '_' character, + * and returns the result.

    + */ + public String readToken() throws IOException { + return readToken("_:."); + } + + /** + *

    This method reads while the stream contains letters or numbers and + * returns the result.

    + * + *

    It also allows any charcters specified by otherChars + * to be considered as part of the token. This allows tokens with + * additional valid characters to be read. otherChars + * may be null if no additional chars are valid.

    + * + * @param otherChars Other valid characters. + */ + public String readToken(String otherChars) throws IOException { + if (otherChars == null) { + otherChars = ""; + } + + StringBuffer buf = new StringBuffer(); + int next = nextChar(); + while (Character.isLetterOrDigit(next) || + (otherChars.indexOf(next) != -1)) { + buf.append((char) next); + next = nextChar(); + } + unread(next); + + // Return the result + return buf.toString(); + } + + /** + *

    This method returns a String of characters from the + * current position in the file until the given character (or end of + * file) is encountered. It will not leave the given character in the + * buffer, so the next character to be read will be the character + * following the given character.

    + * + * @param skipComments true to strip comments. + */ + public String readUntil(int endingChar, boolean skipComments) throws IOException { + if (skipComments) { + // In case we start on a comment and should skip it... + skipCommentsAndWhiteSpace(""); + } + int tmpch; + int next = nextChar(); + StringBuffer buf = new StringBuffer(); + while ((next != endingChar) && (next != -1)) { + switch (next) { + case '\'' : + case '\"' : + if ((skipComments) && (next != endingChar)) { + // In this case, we want to make sure no comments are + // skipped when inside a quote + // + // NOTE: Also means endingChar will not be found in + // a quote. + buf.append((char) next); + buf.append(readUntil(next, false)); + buf.append((char) next); + } else { + buf.append((char) next); + } + break; + case '#' : + case '/' : + case '<' : + // When reading we want to ignore comments, don't skip + // whitespace, though... + if (skipComments) { + unread(next); + skipCommentsAndWhiteSpace(""); + // If same char, read next to prevent infinite loop + // We don't have to go through switch again b/c its + // not the ending char and its not escaped -- so it is + // safe to add. + tmpch = nextChar(); + if (next == tmpch) { + buf.append((char) next); + } else { + // We're somewhere different, unread + unread(tmpch); + } + } else { + buf.append((char) next); + } + break; + case '\\' : + // Escape Character... + next = nextChar(); + if (next == 'n') { + // Special case, insert a '\n' character. + buf.append('\n'); + } else if (next == 't') { + // Special case, insert a '\t' character. + buf.append('\t'); + } else if (next != '\n') { + // add the next char unless it's a return char + buf.append((char) next); + } + break; + default: + buf.append((char) next); + break; + } + next = nextChar(); + } + + // Return the result + return buf.toString(); + } + + /** + *

    This method returns a String of characters from the + * current position in the file until the given String (or end of + * file) is encountered. It will not leave the given String in the + * buffer, so the next character to be read will be the character + * following the given character.

    + * + * @param endingStr The terminating String. + * @param skipComments true to ignore comments. + */ + public String readUntil(String endingStr, boolean skipComments) throws IOException { + // Sanity Check + if ((endingStr == null) || (endingStr.length() == 0)) { + return ""; + } + + // Break String into characters + char arr[] = endingStr.toCharArray(); + int arrlen = arr.length; + + StringBuffer buf = new StringBuffer(""); + int ch = nextChar(); // Read a char to unread + int idx = 1; + do { + // We didn't find the end, push read values back on queue + unread(ch); + for (int cnt = idx-1; cnt > 0; cnt--) { + unread(arr[cnt]); + } + + // Read until the beginning of the end (maybe) + buf.append(readUntil(arr[0], skipComments)); + buf.append(arr[0]); // readUntil reads but doesn't return this char + + // Check to see if we are at the end + for (idx = 1; idx < arrlen; idx++) { + ch = nextChar(); + if (ch != arr[idx]) { + // This is not the end! + break; + } + } + } while ((ch != -1) && (idx < arrlen)); + + // Append the remaining characters (use idx in case we hit eof)... + for (int cnt = 1; cnt < idx; cnt++) { + buf.append(arr[cnt]); + } + + if (arrlen != idx) { + // Didn't find it! + throw new SyntaxException("Unable to find: '" + endingStr + + "'. Read to EOF and gave up. Read: \n" + buf.toString()); + } + + // Return the result + return buf.toString(); + } + + /** + *

    This method skips the given String of characters (usually used to + * skip white space. The contents of the String that is skipped is + * lost. Often you may wish to skip comments as well, use + * {@link TemplateParser#skipCommentsAndWhiteSpace(String)} in this + * case.

    + * + * @param skipChars The white space characters to skip. + * + * @see TemplateParser#skipCommentsAndWhiteSpace(String) + */ + public void skipWhiteSpace(String skipChars) throws IOException { + int next = nextChar(); + while ((next != -1) && (skipChars.indexOf(next) != -1)) { + // Skip... + next = nextChar(); + } + + // This will skip one too many + unread(next); + } + + /** + *

    Normally you don't just want to skip white space, you also want to + * skip comments. This method allows you to do that. It skips + * comments of the following types:

    + * + * + *
    • // - Comment extends to the rest of the line.
    • + *
    • # - Comment extends to the rest of the line.
    • + *
    • /* - Comment extends until closing '*' and '/'.
    • + *
    • <!-- - Comment extends until closing -->.
    + *
    + * + * @param skipChars The white space characters to skip + * + * @see TemplateParser#skipWhiteSpace(String) + */ + public void skipCommentsAndWhiteSpace(String skipChars) throws IOException { + int ch = 0; + while (ch != -1) { + ch = nextChar(); + switch (ch) { + case '#' : + // Skip rest of line + readLine(); + break; + case '/' : + ch = nextChar(); + if (ch == '/') { + // Skip rest of line + readLine(); + } else if (ch == '*') { + // Throw away everything until '*' & '/'. + readUntil("*/", false); + } else { + // Not a comment, don't read + unread(ch); + unread('/'); + ch = -1; // Exit loop + } + break; + case '<' : + ch = nextChar(); // ! + if (ch == '!') { + ch = nextChar(); // - + if (ch == '-') { + ch = nextChar(); // - + if (ch == '-') { + // Ignore HTML-style comment + readUntil("-->", false); + } else { + // Not a comment, probably a mistake... lets + // throw an exception + unread(ch); + unread('-'); + unread('!'); + unread('<'); + throw new IllegalArgumentException("Invalid " + + "comment! Expected comment to begin " + + "with \" + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/faces-config.xml b/jsftemplating/src/main/resources/META-INF/faces-config.xml new file mode 100644 index 0000000..3788881 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/faces-config.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + com.sun.jsftemplating.layout.LayoutViewHandler + com.sun.jsftemplating.el.PageSessionResolver + + + en + + + + + com.sun.jsftemplating.EventComponent + com.sun.jsftemplating.component.EventComponent + + + com.sun.jsftemplating.If + com.sun.jsftemplating.component.If + + + com.sun.jsftemplating.While + com.sun.jsftemplating.component.While + + + com.sun.jsftemplating.ForEach + com.sun.jsftemplating.component.ForEach + + + com.sun.jsftemplating.AjaxRequest + com.sun.jsftemplating.component.AjaxRequest + + + com.sun.jsftemplating.StaticText + com.sun.jsftemplating.component.StaticText + + + + + com.sun.jsftemplating.EventComponent + com.sun.jsftemplating.EventComponent + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.If + com.sun.jsftemplating.If + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.While + com.sun.jsftemplating.While + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.ForEach + com.sun.jsftemplating.ForEach + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.AjaxRequest + com.sun.jsftemplating.AjaxRequest + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.StaticText + com.sun.jsftemplating.StaticText + com.sun.jsftemplating.renderer.TemplateRenderer + + + + + + The "invokeCommandHandlers" ActionListener in this managed bean + capable of dispatching "command" handlers. + + lfCommand + com.sun.jsftemplating.layout.event.CommandActionListener + application + + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/ajaxRequest.xml b/jsftemplating/src/main/resources/META-INF/jsftemplating/ajaxRequest.xml new file mode 100644 index 0000000..dbffaa8 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/ajaxRequest.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/event.xml b/jsftemplating/src/main/resources/META-INF/jsftemplating/event.xml new file mode 100644 index 0000000..f605ec1 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/event.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/foreach.xml b/jsftemplating/src/main/resources/META-INF/jsftemplating/foreach.xml new file mode 100644 index 0000000..5bd84e7 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/foreach.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/if.xml b/jsftemplating/src/main/resources/META-INF/jsftemplating/if.xml new file mode 100644 index 0000000..d5f4af1 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/if.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/layout.dtd b/jsftemplating/src/main/resources/META-INF/jsftemplating/layout.dtd new file mode 100644 index 0000000..4ffb0a7 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/layout.dtd @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/renderChildren.jsf b/jsftemplating/src/main/resources/META-INF/jsftemplating/renderChildren.jsf new file mode 100644 index 0000000..24b1aca --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/renderChildren.jsf @@ -0,0 +1,26 @@ + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/staticText.xml b/jsftemplating/src/main/resources/META-INF/jsftemplating/staticText.xml new file mode 100644 index 0000000..95bf44f --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/staticText.xml @@ -0,0 +1,25 @@ + + diff --git a/jsftemplating/src/main/resources/META-INF/jsftemplating/while.xml b/jsftemplating/src/main/resources/META-INF/jsftemplating/while.xml new file mode 100644 index 0000000..1c1731a --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/jsftemplating/while.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/xhtml-lat1.ent b/jsftemplating/src/main/resources/META-INF/xhtml-lat1.ent new file mode 100644 index 0000000..ffee223 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/xhtml-lat1.ent @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/xhtml-special.ent b/jsftemplating/src/main/resources/META-INF/xhtml-special.ent new file mode 100644 index 0000000..ca358b2 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/xhtml-special.ent @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/xhtml-symbol.ent b/jsftemplating/src/main/resources/META-INF/xhtml-symbol.ent new file mode 100644 index 0000000..63c2abf --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/xhtml-symbol.ent @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/META-INF/xhtml1-transitional.dtd b/jsftemplating/src/main/resources/META-INF/xhtml1-transitional.dtd new file mode 100644 index 0000000..5ea4d75 --- /dev/null +++ b/jsftemplating/src/main/resources/META-INF/xhtml1-transitional.dtd @@ -0,0 +1,1201 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsftemplating/src/main/resources/com/sun/jsftemplating/resource/LogMessages.properties b/jsftemplating/src/main/resources/com/sun/jsftemplating/resource/LogMessages.properties new file mode 100644 index 0000000..20e6aff --- /dev/null +++ b/jsftemplating/src/main/resources/com/sun/jsftemplating/resource/LogMessages.properties @@ -0,0 +1,65 @@ +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the license at +# https://jsftemplating.dev.java.net/cddl1.html or +# jsftemplating/cddl1.txt. +# See the License for the specific language governing +# permissions and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at jsftemplating/cddl1.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# you own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# + +# This file contains localized log messages. Each log message should be +# accompanied by a comment above the message and follow the following format: +# +# JSFT####= +# + +# The following key is reserved. It is not used for localization, but is +# referenced in log messages that do not provide a key. Messages without a +# key should limited to CONFIG through FINEST messages, all other log messages +# should provide a key and be localized. +JSFT0001=This messages does not need to be localized: {0} + +# This key is used when another key is not found... if you see this error, you +# should fix the key that is missing. +JSFT0002=The following Message ID was not found in the the com.sun.enterprise.tools.resource.LogMessages: {0} + +# This key reports that the VariableResolver was unable to find a key. +JSFT0003=VariableResolver was unable to find key ({0}) in ResourceBundle ({1}). + +# This key reports that the requested resource is not available +JSFT0004=The requested resource ({0}) is not available. + +# This shows a message when the .jsf file is not found. +JSFT0005=The requested JSFTemplating page ({0}) was not found. Ignore this message if this request is handled by a .jsp file or some other technology. + +# +JSFT0006=WARNING: Failed to set property ({0}) with (null) value. This occured on the component named ({1}) of type ({2}). + +# Message to help diagnose EL evaluation problems +JSFT0007=WARNING: Failed to evaluate EL expression ({0}). + +# Message for sun:tableRowGroup to indicate that data is null +JSFT0008=WARNING: TableRowGroupFactory expected a List>, but received a List<(null)>. The (null) will be interpretted as a List with length 0. + +# Message for f:validator when it does not resolve to a Validator. +JSFT0009=WARNING: Validator on component ({0}) did not resolve to a javax.faces.validator.Validator! + +# Message for invalid resource +JSFT0010=WARNING: Resource ({0}) is not valid! + +# Message for duplicate component id's +JSFT0011=WARNING: The clientId ({0}) appears more than once! Make sure you have not included it multiple times within the same NamingContainer. diff --git a/jsftemplating/src/main/resources/info.jsf b/jsftemplating/src/main/resources/info.jsf new file mode 100644 index 0000000..67a6bb7 --- /dev/null +++ b/jsftemplating/src/main/resources/info.jsf @@ -0,0 +1,48 @@ +$attribute{isDebug}); +/> + + + + Templating for JavaServer™ Faces Info + + + +
    +

    Powered by Templating for JavaServer™ Faces Technology!

    +

    Visit https://jsftemplating.dev.java.net + to learn more about JSFTemplating.

    +
    +
    + + + $attribute{handlers}); + getGlobalComponentTypeInformation(info=>$attribute{compTypes}); + /> + + +
    +
    + Handlers: +
    +
    $attribute{handlers}
    +
    +
    +
    + ComponentTypes: +
    +
    $attribute{compTypes}
    +
    +
    + + + + + diff --git a/jsftemplating/src/main/resources/jsftemplating.css b/jsftemplating/src/main/resources/jsftemplating.css new file mode 100644 index 0000000..41ebc8e --- /dev/null +++ b/jsftemplating/src/main/resources/jsftemplating.css @@ -0,0 +1,11 @@ + +.lfEditArea .lfEditor {display:inline; border:1px dotted #B66;} +.lfEditAreaOFF .lfEditor {display:inline;} +.lfEditAreaOFF .lfEditor .editMenu {display:none;} +.lfEditorContent {} + +/* Popup Menu Styles */ +.popupArea .lfEditArea {background-color:#FFCCCC;} +.popupMenu {position:absolute; text-align:left; z-index:1000; background-color:#FFF; font-family:Arial,Helvetica,sans-serif; font-size:10pt; width:200px; visibility:hidden; border:2px outset #68D; padding:2px 2px 2px 2px;} +.popupMenuTitle {font-family:Arial,Helvetica,sans-serif; text-align:center; font-weight:bold; background-color: #BBB; margin-bottom: 5px;} +/* .popupMenuItems {padding-left:15px; padding-right:10px;} */ diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/ContextMocker.java b/jsftemplating/src/test/java/com/sun/jsftemplating/ContextMocker.java new file mode 100644 index 0000000..3409a96 --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/ContextMocker.java @@ -0,0 +1,312 @@ +package com.sun.jsftemplating; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.Principal; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import javax.faces.application.Application; +import javax.faces.application.FacesMessage; +import javax.faces.component.UIViewRoot; +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseStream; +import javax.faces.context.ResponseWriter; +import javax.faces.render.RenderKit; + +/** + * Provide a dummy FacesContext for unit tests to pass. + * + * @author Romain Grecourt + */ +public class ContextMocker extends FacesContext { + public ExternalContext _extCtx = new ExternalContextMocker(); + public UIViewRoot _viewRoot = new UIViewRoot(); + + public ContextMocker() { + } + + static ContextMocker _ctx = new ContextMocker(); + public static void init(){ + setCurrentInstance(_ctx); + } + + @Override + public ExternalContext getExternalContext() { + return _extCtx; + } + + @Override + public Application getApplication() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Iterator getClientIdsWithMessages() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public FacesMessage.Severity getMaximumSeverity() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Iterator getMessages() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Iterator getMessages(String clientId) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public RenderKit getRenderKit() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean getRenderResponse() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean getResponseComplete() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public ResponseStream getResponseStream() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void setResponseStream(ResponseStream responseStream) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public ResponseWriter getResponseWriter() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void setResponseWriter(ResponseWriter responseWriter) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public UIViewRoot getViewRoot() { + return _viewRoot; + } + + @Override + public void setViewRoot(UIViewRoot root) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void addMessage(String clientId, FacesMessage message) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void release() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void renderResponse() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void responseComplete() { + throw new UnsupportedOperationException("Not supported."); + } + + public static class ExternalContextMocker extends ExternalContext { + + public ExternalContextMocker() { + } + + public Map _appMap = new HashMap(); + public Map _initParamMap = new HashMap(); + public Map _requestMap = new HashMap(); + + @Override + public Map getApplicationMap() { + return _appMap; + } + @Override + public void dispatch(String path) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public String encodeActionURL(String url) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public String encodeNamespace(String name) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public String encodeResourceURL(String url) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public String getAuthType() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Object getContext() { + return this; + } + + @Override + public String getInitParameter(String name) { + return (String) _initParamMap.get(name); + } + + @Override + public Map getInitParameterMap() { + return _initParamMap; + } + + @Override + public String getRemoteUser() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Object getRequest() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public String getRequestContextPath() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Map getRequestCookieMap() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Map getRequestHeaderMap() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Map getRequestHeaderValuesMap() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Locale getRequestLocale() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Iterator getRequestLocales() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Map getRequestMap() { + return _requestMap; + } + + @Override + public Map getRequestParameterMap() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Iterator getRequestParameterNames() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Map getRequestParameterValuesMap() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public String getRequestPathInfo() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public String getRequestServletPath() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public URL getResource(String path) { + return this.getClass().getClassLoader().getResource(path); + } + + @Override + public InputStream getResourceAsStream(String path) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Set getResourcePaths(String path) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Object getResponse() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Object getSession(boolean create) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Map getSessionMap() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public Principal getUserPrincipal() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean isUserInRole(String role) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void log(String message) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void log(String message, Throwable exception) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void redirect(String url) throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + } +} \ No newline at end of file diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/layout/LayoutDefinitionManagerTest.java b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/LayoutDefinitionManagerTest.java new file mode 100644 index 0000000..aec9dec --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/LayoutDefinitionManagerTest.java @@ -0,0 +1,107 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout; + +import com.sun.jsftemplating.ContextMocker; +import com.sun.jsftemplating.component.factory.basic.StaticTextFactory; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerDefinition; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

    Tests for the {@link LayoutDefinitionManager}.

    + */ +public class LayoutDefinitionManagerTest { + @Before + public void init(){ + ContextMocker.init(); + } + /** + *

    Test to ensure we can read global {@link ComponentType}s.

    + */ + @Test + public void testReadGlobalComponentTypes() { + try { + ComponentType staticText = LayoutDefinitionManager.getGlobalComponentType(null,"staticText"); + Assert.assertTrue("staticTextNull", staticText != null); + ComponentType event = LayoutDefinitionManager.getGlobalComponentType(null,"event"); + Assert.assertTrue("eventNull", event != null); + Assert.assertTrue("eventNotEqualStaticText", staticText != event); + Assert.assertTrue("staticTextType", staticText.getFactory() instanceof StaticTextFactory); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + public void testReadFaceletsTagLibXml() { + //assertNotNull(LayoutDefinitionManager.getGlobalComponentTypes().get("http://java.sun.com/jsf/extensions/dynafaces:scripts")); + } + + /** + *

    Test to ensure we can read global {@link HandlerDefinition}s.

    + */ + @Test + public void testReadGlobalHandlers() { + try { + // Try to get a HandlerDefinition that doesn't exist + HandlerDefinition handler = LayoutDefinitionManager.getGlobalHandlerDefinition("nullHandler"); + Assert.assertTrue("nullHandler", handler == null); + + // Test the "println" handler + handler = LayoutDefinitionManager.getGlobalHandlerDefinition("println"); + Assert.assertTrue("notNullHandler", handler != null); + // Test id + Assert.assertEquals("id", "println", handler.getId()); + // Test 'value' input def. + Assert.assertTrue("valueParamNotNull", handler.getInputDef("value") != null); + Assert.assertEquals("valueParamName", "value", handler.getInputDef("value").getName()); + Assert.assertEquals("valueParamType", String.class, handler.getInputDef("value").getType()); + Assert.assertEquals("valueParamRequired", true, handler.getInputDef("value").isRequired()); + + // Test the "setUIComponentProperty" handler + handler = LayoutDefinitionManager.getGlobalHandlerDefinition("setUIComponentProperty"); + Assert.assertTrue("notNullHandler2", handler != null); + // Test 'value' input def. + Assert.assertTrue("valueParamNotNull2", handler.getInputDef("value") != null); + Assert.assertEquals("valueParamName2", "value", handler.getInputDef("value").getName()); + Assert.assertEquals("valueParamType2", Object.class, handler.getInputDef("value").getType()); + Assert.assertEquals("valueParamRequired2", false, handler.getInputDef("value").isRequired()); + + // Test the "getUIComponentChildren" handler + handler = LayoutDefinitionManager.getGlobalHandlerDefinition("getUIComponentChildren"); + Assert.assertTrue("notNullHandler3", handler != null); + // Test method name + Assert.assertEquals("methodName", "getChildren", handler.getHandlerMethod().getName()); + // Test 'size' output def + Assert.assertTrue("sizeParamNotNull", handler.getOutputDef("size") != null); + Assert.assertEquals("sizeParamName", "size", handler.getOutputDef("size").getName()); + Assert.assertEquals("sizeParamType", Integer.class, handler.getOutputDef("size").getType()); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } +} diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionReaderTest.java b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionReaderTest.java new file mode 100644 index 0000000..f7872f4 --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/facelets/FaceletsLayoutDefinitionReaderTest.java @@ -0,0 +1,178 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.jsftemplating.layout.facelets; + +import com.sun.jsftemplating.ContextMocker; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * + *

    + * Tests for the {@link FaceletsLayoutDefinitionReader}. + *

    + * + */ + +public class FaceletsLayoutDefinitionReaderTest { + + private final ClassLoader cl = FaceletsLayoutDefinitionReaderTest.class.getClassLoader(); + + @Before + public void init(){ + ContextMocker.init(); + } + + /** + * + *

    + * Simple test to ensure we can read a facelets file. + *

    + * + */ + @Test + public void testRead1() { + try { + FaceletsLayoutDefinitionReader reader = + new FaceletsLayoutDefinitionReader("foo", cl.getResource("./simple.xhtml")); + LayoutDefinition ld = reader.read(); + Assert.assertEquals("LayoutDefinition.unevaluatedId", "foo", ld + .getUnevaluatedId()); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(); + } + } + + public void timeTest(String fileName, int iterations) { + try { + java.util.Date start = new java.util.Date(); + for (int x=0; x + * This tests the accuracy of what was read. + *

    + * + * public void testReadAccuracy() { + * + * try { + * + * FaceletsLayoutDefinitionReader reader = + * + * new FaceletsLayoutDefinitionReader("bar", new + * URL(new URL("file:"),".readTest1.jsf")); + * + * LayoutDefinition ld = reader.read(); + * + * List children = ld.getChildLayoutElements(); + * + * if (children.size() < 5) { + * + * throw new RuntimeException("Not enough children!"); + * } + * + * assertEquals("testReadAccuracy.id.y", + * + * "y", children.get(2).getUnevaluatedId()); + * + * assertEquals("testReadAccuracy.value.abcd", + * + * "abcd", ((LayoutComponent) children.get(2)).getOption("value")); + * + * + * + * assertEquals("testReadAccuracy.id.hhh", + * + * "hhh", children.get(3).getUnevaluatedId()); + * + * assertEquals("testReadAccuracy.text.some tree", + * + * "some tree", + * + * ((LayoutComponent) children.get(3)).getOption("text")); + * + * assertEquals("testReadAccuracy.hhh:treeNode1.id", + * + * "treeNode1", + * + * children.get(3).getChildLayoutElements().get(0).getUnevaluatedId()); + * + * assertEquals("testReadAccuracy.hhh:treeNode1.text", + * + * "abc", + * + * ((LayoutComponent) + * children.get(3).getChildLayoutElements().get(0)).getOption("text")); + * + * + * + * assertEquals("testReadAccuracy.id.theform", + * + * "theform", children.get(4).getUnevaluatedId()); + * + * assertEquals("testReadAccuracy.style1", + * + * "border: 1px solid red;", + * + * ((LayoutComponent) children.get(4)).getOption("style")); + * + * + * + * for (LayoutElement elt : children.get(4).getChildLayoutElements()) { + * + * System.out.println(elt.getUnevaluatedId()); + * } + * } catch (Exception ex) { + * + * ex.printStackTrace(); + * + * fail(ex.getMessage()); + * } + * } + * + */ +} diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/EventParserCommandTest.java b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/EventParserCommandTest.java new file mode 100644 index 0000000..54c262c --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/EventParserCommandTest.java @@ -0,0 +1,132 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.ContextMocker; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.handler.Handler; +import java.io.ByteArrayInputStream; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + +/** + *

    Tests for the {@link EventParserCommand}.

    + */ +public class EventParserCommandTest { + @Before + public void init(){ + ContextMocker.init(); + } + /** + *

    Simple test to ensure we can read a template.

    + */ + @Test + public void testHandlerParsing() { + try { + // Create element to contain handlers... + LayoutDefinition elt = new LayoutDefinition("top"); + + // Setup the parser... + TemplateParser parser = new TemplateParser(new ByteArrayInputStream(HANDLERS1)); + parser.open(); // Needed to initialize things. + + // Setup the reader... + TemplateReader reader = new TemplateReader("foo", parser); + reader.pushTag("event"); // The tag will be popped at the end + + // Read the handlers... + command.process(bpc, new ProcessingContextEnvironment(reader, elt, true), "beforeEncode"); + + // Clean up + parser.close(); + + // Test to see if things worked... + Assert.assertEquals("component.id", "top", elt.getUnevaluatedId()); + List handlers = elt.getHandlers("beforeEncode", null); + Assert.assertEquals("handler.size", 3, handlers.size()); + Assert.assertEquals("handler.name1", "println", handlers.get(0).getHandlerDefinition().getId()); + Assert.assertEquals("handler.name2", "setAttribute", handlers.get(1).getHandlerDefinition().getId()); + Assert.assertEquals("handler.name3", "printStackTrace", handlers.get(2).getHandlerDefinition().getId()); + Assert.assertEquals("handler.valueInput1", "This is a test!", handlers.get(0).getInputValue("value")); + Assert.assertEquals("handler.keyInput2", "foo", handlers.get(1).getInputValue("key")); + Assert.assertEquals("handler.valueInput2", "bar", handlers.get(1).getInputValue("value")); + Assert.assertEquals("handler.msgInput3", "test", handlers.get(2).getInputValue("msg")); + Assert.assertEquals("handler.stOutput3.name", "stackTrace", handlers.get(2).getOutputValue("stackTrace").getOutputName()); + Assert.assertEquals("handler.stOutput3.type", + "com.sun.jsftemplating.layout.descriptors.handler.RequestAttributeOutputType", + handlers.get(2).getOutputValue("stackTrace").getOutputType().getClass().getName()); + Assert.assertEquals("handler.stOutput3.mappedName", "st", handlers.get(2).getOutputValue("stackTrace").getOutputKey()); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testHandlerParsing2() { + try { + // Create element to contain handlers... + LayoutDefinition elt = new LayoutDefinition("newTop"); + + // Setup the parser... + TemplateParser parser = new TemplateParser(new ByteArrayInputStream(HANDLERS2)); + parser.open(); // Needed to initialize things. + + // Setup the reader... + TemplateReader reader = new TemplateReader("foo", parser); + reader.pushTag("event"); // The tag will be popped at the end + + // Read the handlers... + command.process(bpc, new ProcessingContextEnvironment(reader, elt, true), "beforeEncode"); + + // Clean up + parser.close(); + + // Test to see if things worked... + Assert.assertEquals("component.id", "newTop", elt.getUnevaluatedId()); + + List handlers = elt.getHandlers("beforeEncode", null); + Assert.assertEquals("handler.size", 1, handlers.size()); + Assert.assertEquals("handler.valueInput1", "test", handlers.get(0).getInputValue("value")); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + private static final byte[] HANDLERS1 = ( + "\nprintln(\"This is a test!\");\n" + + "setAttribute(key='foo' value='bar');" + + "printStackTrace('test', stackTrace=>$attribute{st});/>").getBytes(); + + private static final byte[] HANDLERS2 = "println('test');/>".getBytes(); + + /** + *

    This class should be re-usable and thread-safe.

    + */ + EventParserCommand command = new EventParserCommand(); + BaseProcessingContext bpc = new BaseProcessingContext(); // Not used +} diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateParserTest.java b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateParserTest.java new file mode 100644 index 0000000..58a7b34 --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateParserTest.java @@ -0,0 +1,287 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import java.net.URL; +import org.junit.Assert; +import org.junit.Test; + + +/** + *

    Tests for the "Template" parser.

    + */ +public class TemplateParserTest { + + private final ClassLoader cl = TemplateParserTest.class.getClassLoader(); + + @Test + public void testURL() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("./TemplateFormat.jsf")); + Assert.assertEquals(cl.getResource("./TemplateFormat.jsf").toString(), parser.getURL().toString()); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testOpenClose() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("./TemplateFormat.jsf")); + parser.open(); + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testNextChar1() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("./TemplateFormat.jsf")); + parser.open(); + Assert.assertEquals("testNextChar1-1", '#', parser.nextChar()); + Assert.assertEquals("testNextChar1-2", ' ', parser.nextChar()); + Assert.assertEquals("testNextChar1-3", 'R', parser.nextChar()); + Assert.assertEquals("testNextChar1-4", 'e', parser.nextChar()); + Assert.assertEquals("testNextChar1-5", 'a', parser.nextChar()); + Assert.assertEquals("testNextChar1-6", 'd', parser.nextChar()); + Assert.assertEquals("testNextChar1-7", 'e', parser.nextChar()); + Assert.assertEquals("testNextChar1-8", 'r', parser.nextChar()); + Assert.assertEquals("testNextChar1-9", ' ', parser.nextChar()); + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testUnread() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("./TemplateFormat.jsf")); + parser.open(); + Assert.assertEquals("testNextChar1-1", '#', parser.nextChar()); + Assert.assertEquals("testNextChar1-2", ' ', parser.nextChar()); + parser.unread(' '); + Assert.assertEquals("testNextChar1-3", ' ', parser.nextChar()); + Assert.assertEquals("testNextChar1-4", 'R', parser.nextChar()); + parser.unread('R'); + Assert.assertEquals("testNextChar1-5", 'R', parser.nextChar()); + parser.unread('X'); + Assert.assertEquals("testNextChar1-6", 'X', parser.nextChar()); + Assert.assertEquals("testNextChar1-7", 'e', parser.nextChar()); + parser.unread('1'); + parser.unread('2'); + parser.unread('3'); + Assert.assertEquals("testNextChar1-8", '3', (char) parser.nextChar()); + Assert.assertEquals("testNextChar1-9", '2', (char) parser.nextChar()); + Assert.assertEquals("testNextChar1-10", '1', (char) parser.nextChar()); + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testNVP() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("./TemplateFormat.jsf")); + parser.open(); + // Read some lines + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + + // Move in to the NVP (actually 1 past just to see that that works) + parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); + parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); + parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); + parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); + + NameValuePair nvp = parser.getNVP(null); + + Assert.assertEquals("testNVP1", "ile", nvp.getName()); + Assert.assertEquals("testNVP2", "jsftemplating/js/jsftemplating.js", nvp.getValue()); + Assert.assertEquals("testNVP3", null, nvp.getTarget()); + + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testNVP2() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("TemplateFormat.jsf")); + parser.open(); + + // Read 49 lines + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + + // Move to the output mapping on line 50 + parser.readUntil('v', false); + parser.unread('v'); + + NameValuePair nvp = parser.getNVP(null); + + Assert.assertEquals("testNVP1", "value", nvp.getName()); + Assert.assertEquals("testNVP2", "val", nvp.getValue()); + Assert.assertEquals("testNVP3", "attribute", nvp.getTarget()); + + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testReadLine() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("TemplateFormat.jsf")); + parser.open(); + // Read some lines + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + + // Read some characters + parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); + parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); parser.nextChar(); + + // Make sure we're at the right spot + Assert.assertEquals("testReadLine1", ' ', parser.nextChar()); + Assert.assertEquals("testReadLine2", 'm', parser.nextChar()); + + // Make sure we can read the rest of the line + Assert.assertEquals("testReadLine3", "ulti line comment is hit, skip until end is found", parser.readLine()); + + // Read more lines + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + + // Make sure we're at the right spot + Assert.assertEquals("testReadLine4", "\t ", parser.readLine()); + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testReadToken() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("TemplateFormat.jsf")); + parser.open(); + // Read some lines + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + + // Move to the Script Tag + parser.readUntil('<', false); + + // Test readToken() + Assert.assertEquals("testReadToken", "sun:script", parser.readToken()); + + // Test skipWhiteSpace(); + parser.skipWhiteSpace(TemplateParser.SIMPLE_WHITE_SPACE); + + // Test NVP + NameValuePair nvp = parser.getNVP(null); + + // NVP should be setup correctly + Assert.assertEquals("testNVP1", "file", nvp.getName()); + Assert.assertEquals("testNVP2", "jsftemplating/js/jsftemplating.js", nvp.getValue()); + Assert.assertEquals("testNVP3", null, nvp.getTarget()); + + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + /** + * This test tests the String version of Read Until. + */ + @Test + public void testReadUntilStr() { + try { + TemplateParser parser = new TemplateParser(cl.getResource("./TemplateFormat.jsf")); + parser.open(); + // Read some lines + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); parser.readLine(); + + // Test readUntil. On line before, read until openning comment. + Assert.assertEquals("testReadUntilStr", " // This text should be commented out. should not be parsed.\n ", parser.readUntil("-->", false)); + Assert.assertEquals("testReadUntilStr3", "\n /*\n * This text should be commented out. should not be parsed.\n */", parser.readUntil("*/", false)); + + parser.close(); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + +/* + public void testAdd() { + assertTrue(5 == 6); + } + + public void testEquals() { + assertEquals(12, 12); + assertEquals(12L, 12L); + assertEquals(new Long(12), new Long(12)); + + assertEquals("Size", 12, 13); + assertEquals("Capacity", 12.0, 11.99, 0.0); + } + + public static void main (String[] args) { + junit.textui.TestRunner.run(suite()); + } +*/ +} diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateReaderTest.java b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateReaderTest.java new file mode 100644 index 0000000..914588b --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateReaderTest.java @@ -0,0 +1,209 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.ContextMocker; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutComposition; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + *

    Tests for the {@link TemplateReader}.

    + */ +public class TemplateReaderTest { + + private final ClassLoader cl = TemplateReaderTest.class.getClassLoader(); + + @Before + public void init(){ + ContextMocker.init(); + } + + /** + *

    Simple test to ensure we can read a template.

    + */ + @Test + public void testRead1() { + try { + TemplateReader reader = + new TemplateReader("foo", cl.getResource("./TemplateFormat.jsf")); + LayoutDefinition ld = reader.read(); +// assertEquals("LayoutDefinition.unevaluatedId", "id1", ld.getUnevaluatedId()); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + public void timeTest(String fileName, int iterations) { + try { + java.util.Date start = new java.util.Date(); + for (int x=0; x This test reads TemplateFormat2.jsf. This + * file contains a bunch of {@link LayoutComposition} tags to + * ensure they are read correctly.

    + */ + @Test + public void testReadComposition() { + try { + // Start reading... + TemplateReader reader = + new TemplateReader("foo", cl.getResource("./TemplateFormat2.jsf")); + LayoutDefinition ld = reader.read(); + + // Find the body LayoutComponent + LayoutElement body = ld.findLayoutElement("page").getChildLayoutElement("html"). + getChildLayoutElement("body"); + Assert.assertEquals("testReadComposition.body", + "body", body.getUnevaluatedId()); + + // Find each composition component and check the results... + LayoutElement child = body.getChildLayoutElement("form"); + Assert.assertEquals("testReadComposition.formId", + "form", child.getUnevaluatedId()); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testDecorate() { + try { + // Start reading... + TemplateReader reader = + new TemplateReader("foo", cl.getResource("./TemplateFormat3.jsf")); + LayoutDefinition ld = reader.read(); + + // Find the body LayoutComponent + LayoutElement body = ld.getChildLayoutElement("page"); + body = body.getChildLayoutElement("html").getChildLayoutElement("body"); + Assert.assertEquals("testReadDecorate.body", + "body", body.getUnevaluatedId()); + + // Find each composition component and check the results... + List children = body.getChildLayoutElements(); + String[] results = { + "single1", "single2", "single3", + "single4", "single5", "Template.jsf", + "\"single7\"", "single11", "single12", + "single13", null, null, "mult2" + }; + int[] resultChildSizes = { + 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 1, 2 + }; + int idx = 0; + for (LayoutElement child : children) { + Assert.assertTrue("testReadDecorate.instanceof" + idx, + child instanceof LayoutComposition); + Assert.assertEquals("testReadDecorate.val" + idx, + results[idx], ((LayoutComposition) child).getTemplate()); + Assert.assertEquals("testReadDecorate.childSize" + idx, + resultChildSizes[idx++], + child.getChildLayoutElements().size()); + } + Assert.assertEquals("testReadDecorate.childrenSize", + 13, children.size()); + LayoutElement htmlElt = children.get(5).findLayoutElement("html"); + Assert.assertEquals("testReadDecorate.decorate.page.size", + 2, + (htmlElt == null) ? 0 : htmlElt.getChildLayoutElements().size()); + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + /** + *

    This tests the accuracy of what was read.

    + */ + @Test + public void testReadAccuracy() { + try { + TemplateReader reader = + new TemplateReader("bar", cl.getResource("./readTest1.jsf")); + LayoutDefinition ld = reader.read(); + List children = ld.getChildLayoutElements(); + if (children.size() < 5) { + throw new RuntimeException("Not enough children!"); + } + Assert.assertEquals("testReadAccuracy.id.y", + "y", children.get(2).getUnevaluatedId()); + Assert.assertEquals("testReadAccuracy.value.abcd", + "abcd", ((LayoutComponent) children.get(2)).getOption("value")); + + Assert.assertEquals("testReadAccuracy.id.hhh", + "hhh", children.get(3).getUnevaluatedId()); + Assert.assertEquals("testReadAccuracy.text.some tree", + "some tree", + ((LayoutComponent) children.get(3)).getOption("text")); + Assert.assertEquals("testReadAccuracy.hhh:treeNode1.id", + "treeNode1", + children.get(3).getChildLayoutElements().get(0).getUnevaluatedId()); + Assert.assertEquals("testReadAccuracy.hhh:treeNode1.text", + "abc", + ((LayoutComponent) children.get(3).getChildLayoutElements().get(0)).getOption("text")); + + Assert.assertEquals("testReadAccuracy.id.theform", + "theform", children.get(4).getUnevaluatedId()); + Assert.assertEquals("testReadAccuracy.style1", + "border: 1px solid red;", + ((LayoutComponent) children.get(4)).getOption("style")); + + for (LayoutElement elt : children.get(4).getChildLayoutElements()) { + System.out.println(elt.getUnevaluatedId()); + } + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } +} diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateWriterTest.java b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateWriterTest.java new file mode 100644 index 0000000..a1e451b --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/layout/template/TemplateWriterTest.java @@ -0,0 +1,59 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.jsftemplating.layout.template; + +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import org.junit.Assert; +import org.junit.Test; + +/** + *

    Tests for the {@link TemplateWriter}.

    + */ +public class TemplateWriterTest { + /** + *

    + */ + private final ClassLoader cl = TemplateWriterTest.class.getClassLoader(); + + @Test + public void testWrite1() { + try { + // First read some data + TemplateReader reader = + new TemplateReader("foo", cl.getResource("./TemplateFormat.jsf")); + LayoutDefinition ld = reader.read(); +// assertEquals("LayoutDefinition.unevaluatedId", "id2", ld.getUnevaluatedId()); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + TemplateWriter writer = + new TemplateWriter(stream); + writer.write(ld); +// FIXME: Add some sort of check here +// System.err.println(stream.toString()); + } catch (IOException ex) { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } +} diff --git a/jsftemplating/src/test/java/com/sun/jsftemplating/util/SimplePatternMatcherTest.java b/jsftemplating/src/test/java/com/sun/jsftemplating/util/SimplePatternMatcherTest.java new file mode 100644 index 0000000..094c028 --- /dev/null +++ b/jsftemplating/src/test/java/com/sun/jsftemplating/util/SimplePatternMatcherTest.java @@ -0,0 +1,205 @@ +/** + * + */ +package com.sun.jsftemplating.util; + +import java.util.Collection; +import org.junit.Assert; + +import org.junit.Test; + +/** + * TestCase for SimplePatternMatcher. + * + * @author Imre Oßwald (io@emx.jevelopers.com) + * + */ +public class SimplePatternMatcherTest { + + /** + * Test method for + * {@link com.sun.jsftemplating.util.SimplePatternMatcher#matches(java.lang.String)}. + */ + @Test + public void testMatches() { + long start = System.nanoTime(); + + Exception e = null; + + MatchTest fullPath = new MatchTest("/some/folder/view.id"); + MatchTest all = new MatchTest("*"); + MatchTest suffix = new MatchTest("*.jsft"); + MatchTest prefix = new MatchTest("/some/*"); + MatchTest oneStar = new MatchTest("/some/*/test.jsp"); + MatchTest complex = new MatchTest("/*/config/*/page?.jsp"); + + long start2 = System.nanoTime(); + + try { + new MatchTest(null); + } catch (NullPointerException npe) { + e = npe; + } + Assert.assertNotNull(e); + e = null; + + for (int i = 0; i < 100; i++) { // run common cases more often for + // timing + fullPath.setMatching("/some/folder/view.id"); + fullPath.setNonMatching(null, "", "/test", "/some", + "/some/folder/view.i", "/some/folder/view.id2"); + fullPath.test(); + + all.setMatching("", "/", "/page.jsp", "/some/page.jsp"); + all.setNonMatching((String) null); + all.test(); + + suffix.setMatching("/.jsft", "/a.jsft", "/folder/x.jsft"); + suffix.setNonMatching(null, "", "/jsft", "somexjsft", "/some.jsp", + "/someother.jsftx"); + suffix.test(); + + prefix.setMatching("/some/", "/some/page", "/some/page.jsp", + "/some/more/page.jsp"); + prefix.setNonMatching(null, "", "/", "/some", "/somex/", + "/somex/page.jsp"); + prefix.test(); + } + + oneStar.setMatching("/some/thing/test.jsp", + "/some/thing/more/test.jsp", "/some/even.more/test.jsp"); + oneStar.setNonMatching(null, "/test.jsp", "/somelonger/test.jsp", + "/some/more/test.jsft"); + oneStar.test(); + + complex.setMatching("/f1/config/downloads/page1.jsp", + "//config//page2.jsp", "/f2/config/one/two/three/pageA.jsp", + "/a/b/c/d/config/e/f/g/pageX.jsp"); + complex.setNonMatching(null, "x/config//pageN.jsp", + "/x/config/x/page12.jsp", "/f1/config/downloads/page1.jspx", + "/f1/nonconfig/downloads/pageA.jsp"); + complex.test(); + long end = System.nanoTime(); + System.out.println("testMatches() took: " + ((end - start) / 1000) + + " mics"); + System.out.println("matching took: " + ((end - start2) / 1000) + + " mics"); + } + + /** + * Test method for + * {@link com.sun.jsftemplating.util.SimplePatternMatcher#parseMultiPatternString(String, String)}. + */ + @Test + public void testParseMultiPatter() { + String mpattern = null; + Collection result = null; + + result = SimplePatternMatcher.parseMultiPatternString(mpattern, ";"); + Assert.assertTrue("null pattern should return an empty collection", result + .isEmpty()); + + mpattern = ""; + result = SimplePatternMatcher.parseMultiPatternString(mpattern, ";"); + Assert.assertTrue("empty pattern should return an empty collection", result + .isEmpty()); + + mpattern = " \n\t "; + result = SimplePatternMatcher.parseMultiPatternString(mpattern, ";"); + Assert.assertTrue("trimmed empty pattern should return an empty collection", + result.isEmpty()); + + mpattern = "; ; ; ; ;; ;"; + result = SimplePatternMatcher.parseMultiPatternString(mpattern, ";"); + Assert.assertTrue( + "multiple (trimmed) empty pattern should return an empty collection", + result.isEmpty()); + + mpattern = "/faces/*;;*.jsf"; + result = SimplePatternMatcher.parseMultiPatternString(mpattern, ";"); + Assert.assertTrue("'" + mpattern + "' should return an collection of size==2", + result.size() == 2); + } + + /** + * Test method for + * {@link com.sun.jsftemplating.util.SimplePatternMatcher#regexify(java.lang.CharSequence)}. + */ + @Test + public void testRegexify() { + long start = System.nanoTime(); + + String source = null; + String expected = null; + Exception e = null; + try { + SimplePatternMatcher.regexify(source); + } catch (NullPointerException npe) { + e = npe; + } + Assert.assertNotNull(e); + e = null; + + source = ""; + expected = source; + Assert.assertEquals(SimplePatternMatcher.regexify(source), expected); + + source = "/something/without/any/special/chars"; + expected = source; + Assert.assertEquals(SimplePatternMatcher.regexify(source), expected); + + source = "testingOne.inTheViewId"; + expected = "testingOne\\.inTheViewId"; + Assert.assertEquals(SimplePatternMatcher.regexify(source), expected); + + source = "/testing.points/in.the./view.id"; + expected = "/testing\\.points/in\\.the\\./view\\.id"; + Assert.assertEquals(SimplePatternMatcher.regexify(source), expected); + + source = "testingOne*inTheViewId"; + expected = "testingOne(.*)inTheViewId"; + Assert.assertEquals(SimplePatternMatcher.regexify(source), expected); + + source = "testing*Multiple*in*The*View*Id"; + expected = "testing(.*)Multiple(.*)in(.*)The(.*)View(.*)Id"; + Assert.assertEquals(SimplePatternMatcher.regexify(source), expected); + + source = "testingQuestionMarks?"; + expected = "testingQuestionMarks."; + Assert.assertEquals(SimplePatternMatcher.regexify(source), expected); + long end = System.nanoTime(); + System.out.println("regexify() took: " + ((end - start) / 1000) + + " mics"); + + } + + private static final class MatchTest { + private SimplePatternMatcher matcher; + private String[] matching; + private String[] nonMatching; + + MatchTest(String pattern) { + this.matcher = new SimplePatternMatcher(pattern); + } + + void setMatching(String... strings) { + this.matching = strings; + } + + void setNonMatching(String... strings) { + this.nonMatching = strings; + } + + @Test + void test() { + for (String match : matching) { + Assert.assertTrue(match + " should match " + this.matcher, + this.matcher.matches(match)); + } + for (String dontMatch : nonMatching) { + Assert.assertFalse(dontMatch + " should not match " + this.matcher, + this.matcher.matches(dontMatch)); + } + } + } +} diff --git a/jsftemplating/src/test/resources/Template.jsf b/jsftemplating/src/test/resources/Template.jsf new file mode 100644 index 0000000..82be35e --- /dev/null +++ b/jsftemplating/src/test/resources/Template.jsf @@ -0,0 +1,21 @@ + + + + The title + + + + + + + + "3repeat default + + + + " + + + + + diff --git a/jsftemplating/src/test/resources/TemplateFormat.jsf b/jsftemplating/src/test/resources/TemplateFormat.jsf new file mode 100644 index 0000000..758a140 --- /dev/null +++ b/jsftemplating/src/test/resources/TemplateFormat.jsf @@ -0,0 +1,62 @@ +# Reader requirements: +# - Single pass reading. +# - Read until one of the following is encountered: +# '<', '#', "//", "/*", " + /* + * This text should be commented out. should not be parsed. + */ + +"

    +"

    +" single or double quotes ("'" or "'") allow text or markup + " to be written directly to the output. The rest of a single +" line will be written out. +"
    +"

    +' + '

    The following uses an actionListener, beforeEncode, and a command event...

    +' + + "Hyperlink Text there should be a <b> between "Text" and 'there'. + + $attribute{val}); + println(value="$attribute{val}") + /> + + + + + + "Facets may be added using "!facet " infront of the type + + + + diff --git a/jsftemplating/src/test/resources/TemplateFormat2.jsf b/jsftemplating/src/test/resources/TemplateFormat2.jsf new file mode 100644 index 0000000..39e310d --- /dev/null +++ b/jsftemplating/src/test/resources/TemplateFormat2.jsf @@ -0,0 +1,23 @@ + + + + The title + + + + + "Default text + + "

    Header

    + + + "
    Body
    + + + "Repeat Me! + + + +
    +
    +
    diff --git a/jsftemplating/src/test/resources/TemplateFormat3.jsf b/jsftemplating/src/test/resources/TemplateFormat3.jsf new file mode 100644 index 0000000..34c679a --- /dev/null +++ b/jsftemplating/src/test/resources/TemplateFormat3.jsf @@ -0,0 +1,42 @@ + + + + The title + + + + + + + + + + + + + + + + + + + +

    +

    Test
    +

    +
    + + + + +
    +
    +
    diff --git a/jsftemplating/src/test/resources/readTest1.jsf b/jsftemplating/src/test/resources/readTest1.jsf new file mode 100644 index 0000000..e6dfbb5 --- /dev/null +++ b/jsftemplating/src/test/resources/readTest1.jsf @@ -0,0 +1,17 @@ +/* + * This file is used to test the TemplateReader, it is not meant to serve + * as a best-practice example + */ +'
    Hello World©! +"
    Hello World©! + + + + + + + + + + + diff --git a/jsftemplating/src/test/resources/simple.xhtml b/jsftemplating/src/test/resources/simple.xhtml new file mode 100644 index 0000000..dbca55a --- /dev/null +++ b/jsftemplating/src/test/resources/simple.xhtml @@ -0,0 +1,11 @@ + + + + #{2+2} +
    + + This should be all there is! + + #{2 + 2} + + diff --git a/jsftemplating/src/test/resources/simpleTemplate.xhtml b/jsftemplating/src/test/resources/simpleTemplate.xhtml new file mode 100644 index 0000000..057bad5 --- /dev/null +++ b/jsftemplating/src/test/resources/simpleTemplate.xhtml @@ -0,0 +1,8 @@ + + + + #{3+3} +
    + #{3 + 3} + + diff --git a/jsftemplating/src/test/resources/speed-l.jsf b/jsftemplating/src/test/resources/speed-l.jsf new file mode 100644 index 0000000..50a859f --- /dev/null +++ b/jsftemplating/src/test/resources/speed-l.jsf @@ -0,0 +1,1430 @@ + +" +" + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    +" +" diff --git a/jsftemplating/src/test/resources/speed-l.xhtml b/jsftemplating/src/test/resources/speed-l.xhtml new file mode 100644 index 0000000..166e4cc --- /dev/null +++ b/jsftemplating/src/test/resources/speed-l.xhtml @@ -0,0 +1,1431 @@ + + + + + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + diff --git a/jsftemplating/src/test/resources/speed-m.jsf b/jsftemplating/src/test/resources/speed-m.jsf new file mode 100644 index 0000000..d14158f --- /dev/null +++ b/jsftemplating/src/test/resources/speed-m.jsf @@ -0,0 +1,170 @@ + +" +" + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    +" +" diff --git a/jsftemplating/src/test/resources/speed-m.xhtml b/jsftemplating/src/test/resources/speed-m.xhtml new file mode 100644 index 0000000..3acca9f --- /dev/null +++ b/jsftemplating/src/test/resources/speed-m.xhtml @@ -0,0 +1,171 @@ + + + + + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + diff --git a/jsftemplating/src/test/resources/speed-s.jsf b/jsftemplating/src/test/resources/speed-s.jsf new file mode 100644 index 0000000..951288b --- /dev/null +++ b/jsftemplating/src/test/resources/speed-s.jsf @@ -0,0 +1,30 @@ + +" +" + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    +" +" diff --git a/jsftemplating/src/test/resources/speed-s.xhtml b/jsftemplating/src/test/resources/speed-s.xhtml new file mode 100644 index 0000000..e5009f9 --- /dev/null +++ b/jsftemplating/src/test/resources/speed-s.xhtml @@ -0,0 +1,31 @@ + + + + + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + diff --git a/jsftemplating/src/test/resources/speed-xl.jsf b/jsftemplating/src/test/resources/speed-xl.jsf new file mode 100644 index 0000000..7ebab7d --- /dev/null +++ b/jsftemplating/src/test/resources/speed-xl.jsf @@ -0,0 +1,14030 @@ + +" +" + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    + + + + $attribute{output}); + /> + + +"
    + #{2 + 2} + +
    + +
    +" +" diff --git a/jsftemplating/src/test/resources/speed-xl.xhtml b/jsftemplating/src/test/resources/speed-xl.xhtml new file mode 100644 index 0000000..5bc7f18 --- /dev/null +++ b/jsftemplating/src/test/resources/speed-xl.xhtml @@ -0,0 +1,14031 @@ + + + + + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + + + + getUIComponentProperty(component="jkl" name="propName" value=>$attribute{output}); + + + +
    + #{2 + 2} + +
    + +
    + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..aa51cab --- /dev/null +++ b/pom.xml @@ -0,0 +1,346 @@ + + + + + 4.0.0 + + net.java + jvnet-parent + 5 + + + com.sun.jsftemplating + jsftemplating-parent + 2.1.1-SNAPSHOT + pom + + + Oracle Corporation + http://www.oracle.com + + + https://jsftemplating.java.net + + + + CDDL + GPLv2 with classpath exception + https://glassfish.java.net/nonav/public/CDDL+GPL_1_1.html + repo + A business-friendly OSS license + + + + + JIRA + http://java.net/jira/browse/JSFTEMPLATING + + + + scm:svn:https://svn.java.net/svn/jsftemplating~svn/trunk + scm:svn:https://svn.java.net/svn/jsftemplating~svn/trunk + https://svn.java.net/svn/jsftemplating~svn/trunk + + + + + dev + https://java.net/projects/jsftemplating/lists + dev@jsftemplating.java.net + http://java.net/projects/jsftemplating/lists/dev/archive + + + users + http://java.net/projects/jsftemplating/lists + users@jsftemplating.java.net + http://java.net/projects/jsftemplating/lists/users/archive + + + issues + http://java.net/projects/jsftemplating/lists + issues@jsftemplating.java.net + http://java.net/projects/jsftemplating/lists/issues/archive + + + commits + http://java.net/projects/jsftemplating/lists + commits@jsftemplating.java.net + http://java.net/projects/jsftemplating/lists/commits/archive + + + + + + website.java.net + dav:https://website.java.net/website/jsftemplating + + + + + jsft + jsftemplating + jsftemplating-dt + + + + 1.6.0 + 3.0.3 + UTF-8 + + + + + + org.glassfish.hk2 + osgiversion-maven-plugin + 2.3.0-b05 + + + compute-osgi-version + initialize + + compute-osgi-version + + + qualifier + project.osgi.version + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + enforce-versions + + enforce + + + + + [${jdk.version},) + You need JDK ${jdk.version} and above! + + + [${mvn.version},) + You need Maven ${mvn.version} or above! + + + + + + + + org.apache.maven.plugins + maven-remote-resources-plugin + 1.2.1 + + + add-license.txt + + process + + generate-resources + + + org.glassfish:legal:1.1 + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.6 + 1.6 + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.4 + + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + 10 + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9 + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + true + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.0-beta-1 + + + org.apache.maven.plugins + maven-site-plugin + 3.2 + + true + true + + + + org.codehaus.mojo + findbugs-maven-plugin + 2.5.4 + + ${findbugs.skip} + ${findbugs.threshold} + true + + exclude-common.xml,${findbugs.exclude} + + + + + org.glassfish.findbugs + findbugs + 1.0 + + + + + org.apache.felix + maven-bundle-plugin + 2.3.4 + + + + + ${project.osgi.version} + + <_include>-${basedir}/osgi.bundle + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + true + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.8 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.17 + + 0 + + com.sun.jsftemplating.DEBUG + true + + + + + + + + + + + javax.servlet + javax.servlet-api + 3.0.1 + + + org.glassfish + javax.faces + 2.2.6 + + + javax.faces + javax.faces-api + 2.2 + + + javax.el + el-api + 2.2 + + + com.sun.woodstock.dependlibs + dataprovider + 1.0 + + + junit + junit + 4.11 + test + + + + diff --git a/release-notes.txt b/release-notes.txt new file mode 100644 index 0000000..04548cf --- /dev/null +++ b/release-notes.txt @@ -0,0 +1,57 @@ + +JSFTemplating 2.1.0 +============================================================ +- Created new "jsft.jar" which focuses on supporting true Facelets while + providing features, such as JSFT's event model. +- Added new EL-based event handling to jsft.jar. +- Added initial implementation of "deferredFragments" -- allowing slow data + to be processed in parallel so rendering can be sped up. WIP +- Minor NPE bug fix re: (null) viewId being passed in -- why do that? + +JSFTemplating 2.0.4 +============================================================ +- Fixed NPE in ResourceContentSource when empty file ("") was requested. +- Added ability to define suffix resource exclusions (i.e. *.jsf, + *.xml, etc.) for FileStreamer +- Changed build to no longer generate jsftemplating-base.jar +- Added flag for components to suppress duplicate id checking in debug mode. + Flag is "skipIdCheck" and should be set as an attribute in the .jsf file + of the component which should avoid checking for duplicate ids. +- Added ability to define "instance" handlers. These are essentially macro + handlers that can be defined on a page (LayoutDefinition actually). This + is done by doing something like this: + + + println("Whatever handler you want"); + asMany(value="as you want"); + println("Use scopes to #{pass.info} to/from embedded handlers."); + + + You can then use it in an event: handler-id-here(); + + Parameter passing directly via the handler invocation is not currently + supported. +- Updated the faces-config.xml file to use 1.2 (previously referring to 1.1) + +JSFTemplating 2.0.3 +============================================================ +- Made duplicate component ids in debug mode non-fatal, but + still logs a warning message. +- Now building for Java 6 + +JSFTemplating 2.0.2 +============================================================ +- Changed urlencode handler to use UTF-8 if no encoding is specified + (vs. system default), also changed behavior to return null if null + is given to encode (vs. throwing a NPE). +- Ensured JSFT "template" LayoutDefinitionManager is used first (unless + overridden) and that no LDM's are added more than once. +- Removed DynaFaces references (DF is no longer supported w/ this version) +- Added change to no process JSF2 Ajax requests targeted to @all via JSF2 + but instead handle them as a Full Page request. + +JSFTemplating 2.1.1 +============================================================ +- Move the build system to Maven 3.x +- Updated the Annotation Processor to JSR 169 in order to support JSK8 (APT has been removed effectively in JDK8). +- refactored events and task to match the state of com.sun.jsft in version 2.1.0. diff --git a/release.sh b/release.sh new file mode 100644 index 0000000..a13fcf8 --- /dev/null +++ b/release.sh @@ -0,0 +1,36 @@ +#!/bin/sh +#------------------------------------------------------ +#-- BE SURE TO HAVE THE FOLLOWING IN YOUR SETTINGS.XML +#------------------------------------------------------ +# +# +# +# jvnet-nexus-staging +# jvnet_id +# password +# +# +# +# +# release +# +# -Dhttps.proxyHost=www-proxy.us.oracle.com -Dhttps.proxyPort=80 -Dgpg.passphrase=glassfish -Pjvnet-release +# +# +# false +# +# +# + +# see the following URL for gpg issues +# https://docs.sonatype.org/display/Repository/How+To+Generate+PGP+Signatures+With+Maven#HowToGeneratePGPSignaturesWithMaven-GenerateaKeyPair + +# login to nexus at maven.java.net and release (Close) the artifact +# https://maven.java.net/index.html#stagingRepositories + +# More information: +# https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-8.ReleaseIt +# http://aseng-wiki.us.oracle.com/asengwiki/display/GlassFish/Migrating+Maven+deployment+to+maven.java.net + +mvn -B release:prepare -Prelease +mvn -B release:perform -Prelease diff --git a/samples/DemoNBProject/build.xml b/samples/DemoNBProject/build.xml new file mode 100644 index 0000000..13ab376 --- /dev/null +++ b/samples/DemoNBProject/build.xml @@ -0,0 +1,92 @@ + + + + + + Builds, tests, and runs the project DemoNBProject. + + + + + + + + + + + + + + + + + + + Building with apt: + + + + diff --git a/samples/DemoNBProject/ext-lib/ant-apt.jar b/samples/DemoNBProject/ext-lib/ant-apt.jar new file mode 100644 index 0000000..96b3048 Binary files /dev/null and b/samples/DemoNBProject/ext-lib/ant-apt.jar differ diff --git a/samples/DemoNBProject/ext-lib/jsftemplating-dt.jar b/samples/DemoNBProject/ext-lib/jsftemplating-dt.jar new file mode 100644 index 0000000..dab1aae Binary files /dev/null and b/samples/DemoNBProject/ext-lib/jsftemplating-dt.jar differ diff --git a/samples/DemoNBProject/nbproject/ant-deploy.xml b/samples/DemoNBProject/nbproject/ant-deploy.xml new file mode 100644 index 0000000..7ec8e30 --- /dev/null +++ b/samples/DemoNBProject/nbproject/ant-deploy.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${lefty}?xml version="1.0" encoding="UTF-8"?${righty} +${lefty}!DOCTYPE resources PUBLIC + "-//Sun Microsystems Inc.//DTD Application Server 9.0 Resource Definitions //EN" + "${sjsas.root}/lib/dtds/sun-resources_1_2.dtd"${righty} +${lefty}resources${righty} +${lefty}/resources${righty} + + + + + + + +]]> + + + + +]]> + + + + + + + ]]> + + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + diff --git a/samples/DemoNBProject/nbproject/build-impl.xml b/samples/DemoNBProject/nbproject/build-impl.xml new file mode 100644 index 0000000..2ab9b04 --- /dev/null +++ b/samples/DemoNBProject/nbproject/build-impl.xml @@ -0,0 +1,711 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set build.web.dir + Must set build.generated.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.war + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.jsp.includes + + + + + + + + + + + + + + + + + + + + Must select a file in the IDE or set jsp.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Browser not found, cannot launch the deployed application. Try to set the BROWSER environment variable. + + + Launching ${browse.url} + + + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/DemoNBProject/nbproject/genfiles.properties b/samples/DemoNBProject/nbproject/genfiles.properties new file mode 100644 index 0000000..36a264f --- /dev/null +++ b/samples/DemoNBProject/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=ecd76d3c +build.xml.script.CRC32=697b9d5c +build.xml.stylesheet.CRC32=95be3570 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=cef6f6c4 +nbproject/build-impl.xml.script.CRC32=72bc159a +nbproject/build-impl.xml.stylesheet.CRC32=ac43bae1 diff --git a/samples/DemoNBProject/nbproject/project.properties b/samples/DemoNBProject/nbproject/project.properties new file mode 100644 index 0000000..3eb997f --- /dev/null +++ b/samples/DemoNBProject/nbproject/project.properties @@ -0,0 +1,81 @@ +build.classes.dir=${build.web.dir}/WEB-INF/classes +build.classes.excludes=**/*.java,**/*.form +build.dir=build +build.ear.classes.dir=${build.ear.web.dir}/WEB-INF/classes +build.ear.web.dir=${build.dir}/ear-module +build.generated.dir=${build.dir}/generated +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +build.web.dir=${build.dir}/web +build.web.excludes=${build.classes.excludes} +client.urlPart= +compile.jsps=false +conf.dir=${source.root}/conf +debug.classpath=${javac.classpath}:${build.classes.dir}:${build.ear.classes.dir} +debug.test.classpath=\ + ${run.test.classpath} +display.browser=true +dist.dir=dist +dist.ear.war=${dist.dir}/${war.ear.name} +dist.javadoc.dir=${dist.dir}/javadoc +dist.war=${dist.dir}/${war.name} +file.reference.ant-apt.jar=ext-lib/ant-apt.jar +file.reference.dataprovider.jar-1=web/WEB-INF/lib/dataprovider.jar +file.reference.jsftemplating-dt.jar=ext-lib/jsftemplating-dt.jar +file.reference.jsftemplating-dynafaces-0.1.jar-1=web/WEB-INF/lib/jsftemplating-dynafaces-0.1.jar +file.reference.jsftemplating.jar-1=web/WEB-INF/lib/jsftemplating.jar +file.reference.json2.jar-1=web/WEB-INF/lib/json2.jar +file.reference.webui-jsf-suntheme.jar-1=web/WEB-INF/lib/webui-jsf-suntheme.jar +file.reference.webui-jsf.jar-1=web/WEB-INF/lib/webui-jsf.jar +j2ee.platform=1.5 +j2ee.server.type=J2EE +jar.compress=false +javac.classpath=\ + ${file.reference.jsftemplating.jar-1}:\ + ${file.reference.dataprovider.jar-1}:\ + ${file.reference.webui-jsf-suntheme.jar-1}:\ + ${file.reference.jsftemplating-dynafaces-0.1.jar-1}:\ + ${file.reference.webui-jsf.jar-1}:\ + ${file.reference.json2.jar-1}:\ + ${file.reference.ant-apt.jar}:\ + ${file.reference.jsftemplating-dt.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.debug=true +javac.deprecation=false +javac.source=${default.javac.source} +javac.target=${default.javac.target} +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding= +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.preview=true +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jspcompilation.classpath=${jspc.classpath}:${javac.classpath} +lib.dir=${web.docbase.dir}/WEB-INF/lib +platform.active=default_platform +resource.dir=setup +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +# Space-separated list of JVM arguments used when running class with main method +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value): +runmain.jvmargs= +source.root=src +src.dir=${source.root}/java +test.src.dir=test +war.content.additional= +war.ear.name=DemoNBProject.war +war.name=DemoNBProject.war +war.package=true +web.docbase.dir=web diff --git a/samples/DemoNBProject/nbproject/project.xml b/samples/DemoNBProject/nbproject/project.xml new file mode 100644 index 0000000..b4da771 --- /dev/null +++ b/samples/DemoNBProject/nbproject/project.xml @@ -0,0 +1,49 @@ + + + org.netbeans.modules.web.project + + + DemoNBProject + 1.6 + + + ${file.reference.jsftemplating.jar-1} + WEB-INF/lib + + + ${file.reference.dataprovider.jar-1} + WEB-INF/lib + + + ${file.reference.webui-jsf-suntheme.jar-1} + WEB-INF/lib + + + ${file.reference.jsftemplating-dynafaces-0.1.jar-1} + WEB-INF/lib + + + ${file.reference.webui-jsf.jar-1} + WEB-INF/lib + + + ${file.reference.json2.jar-1} + WEB-INF/lib + + + ${file.reference.ant-apt.jar} + + + ${file.reference.jsftemplating-dt.jar} + + + + + + + + + + + + diff --git a/samples/DemoNBProject/src/conf/MANIFEST.MF b/samples/DemoNBProject/src/conf/MANIFEST.MF new file mode 100644 index 0000000..59499bc --- /dev/null +++ b/samples/DemoNBProject/src/conf/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/samples/DemoNBProject/src/java/MyBundle.properties b/samples/DemoNBProject/src/java/MyBundle.properties new file mode 100644 index 0000000..6558f17 --- /dev/null +++ b/samples/DemoNBProject/src/java/MyBundle.properties @@ -0,0 +1 @@ +welcome.msg=Welcome Message from MyBundle.properties file. diff --git a/samples/DemoNBProject/src/java/org/example/handlers/ExampleHandlers.java b/samples/DemoNBProject/src/java/org/example/handlers/ExampleHandlers.java new file mode 100644 index 0000000..75d7fee --- /dev/null +++ b/samples/DemoNBProject/src/java/org/example/handlers/ExampleHandlers.java @@ -0,0 +1,56 @@ +package org.example.handlers; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; + + +/** + *

    This class is written to demonstrate how to write a + * Handler.

    + */ +public class ExampleHandlers { + + /** + *

    This is a handler for the demo app. It contains 1 input and 1 + * output, both of type String. This handler will look at the input + * and produce a response to that input. It is looking for the input + * to equal 'abc', it provides the user a hint if they type something + * other than abc. If no input is provided, it prompts the user for + * input.

    + * + *

    Because handlers are defined via @annotations, you can move them + * to from one file or package to another without changing your pages + * that use the handlers. Also notice that this Handler has an "id" + * that is different from the method name. The "id" must be unique + * within the application. It is good practice to qualify all + * handlers to avoid a naming conflict.

    + * + * @param context The HandlerContext. + */ + @Handler(id="Test.getResponse", + input={ + @HandlerInput(name="userInput", type=String.class) + }, + output={ + @HandlerOutput(name="response", type=String.class) + }) + public static void calculateResponse(HandlerContext context) { + // Get the input. + String in = (String) context.getInputValue("userInput"); + + // Do business logic... + String resp = "Type something and click 'Go!'"; + if (in != null) { + if (in.equals("abc")) { + resp = "Congratulations, you did it!"; + } else if (!in.equals("")) { + resp = "You typed " + in + ", try typing 'abc'."; + } + } + + // Set the output. + context.setOutputValue("response", resp); + } +} diff --git a/samples/DemoNBProject/web/Hello.jsp b/samples/DemoNBProject/web/Hello.jsp new file mode 100644 index 0000000..980a0d5 --- /dev/null +++ b/samples/DemoNBProject/web/Hello.jsp @@ -0,0 +1 @@ +Hello World! diff --git a/samples/DemoNBProject/web/HelloWorld.jsf b/samples/DemoNBProject/web/HelloWorld.jsf new file mode 100644 index 0000000..23bfe4f --- /dev/null +++ b/samples/DemoNBProject/web/HelloWorld.jsf @@ -0,0 +1 @@ +"Hello World! diff --git a/samples/DemoNBProject/web/WEB-INF/lib/dataprovider.jar b/samples/DemoNBProject/web/WEB-INF/lib/dataprovider.jar new file mode 100644 index 0000000..ea5e38b Binary files /dev/null and b/samples/DemoNBProject/web/WEB-INF/lib/dataprovider.jar differ diff --git a/samples/DemoNBProject/web/WEB-INF/lib/jsftemplating-dynafaces-0.1.jar b/samples/DemoNBProject/web/WEB-INF/lib/jsftemplating-dynafaces-0.1.jar new file mode 100644 index 0000000..186b199 Binary files /dev/null and b/samples/DemoNBProject/web/WEB-INF/lib/jsftemplating-dynafaces-0.1.jar differ diff --git a/samples/DemoNBProject/web/WEB-INF/lib/jsftemplating.jar b/samples/DemoNBProject/web/WEB-INF/lib/jsftemplating.jar new file mode 100644 index 0000000..9c07b94 Binary files /dev/null and b/samples/DemoNBProject/web/WEB-INF/lib/jsftemplating.jar differ diff --git a/samples/DemoNBProject/web/WEB-INF/lib/json2.jar b/samples/DemoNBProject/web/WEB-INF/lib/json2.jar new file mode 100644 index 0000000..ea7645d Binary files /dev/null and b/samples/DemoNBProject/web/WEB-INF/lib/json2.jar differ diff --git a/samples/DemoNBProject/web/WEB-INF/lib/webui-jsf-suntheme.jar b/samples/DemoNBProject/web/WEB-INF/lib/webui-jsf-suntheme.jar new file mode 100644 index 0000000..afeca18 Binary files /dev/null and b/samples/DemoNBProject/web/WEB-INF/lib/webui-jsf-suntheme.jar differ diff --git a/samples/DemoNBProject/web/WEB-INF/lib/webui-jsf.jar b/samples/DemoNBProject/web/WEB-INF/lib/webui-jsf.jar new file mode 100644 index 0000000..2a22329 Binary files /dev/null and b/samples/DemoNBProject/web/WEB-INF/lib/webui-jsf.jar differ diff --git a/samples/DemoNBProject/web/WEB-INF/sun-web.xml b/samples/DemoNBProject/web/WEB-INF/sun-web.xml new file mode 100644 index 0000000..c25e2be --- /dev/null +++ b/samples/DemoNBProject/web/WEB-INF/sun-web.xml @@ -0,0 +1,14 @@ + + + + /DemoNBProject + + + + Enable debug info compilation in the generated servlet class + + + Maintain a one-to-one correspondence between static content and the generated servlet class' java code + + + diff --git a/samples/DemoNBProject/web/WEB-INF/web.xml b/samples/DemoNBProject/web/WEB-INF/web.xml new file mode 100644 index 0000000..cbd510a --- /dev/null +++ b/samples/DemoNBProject/web/WEB-INF/web.xml @@ -0,0 +1,38 @@ + + + + + com.sun.jsftemplating.DEBUG + true + + + FacesServlet + javax.faces.webapp.FacesServlet + + + javax.faces.LIFECYCLE_ID + com.sun.faces.lifecycle.PARTIAL + + 1 + + + ThemeServlet + com.sun.webui.theme.ThemeServlet + 2 + + + FacesServlet + /resource/* + + + FacesServlet + *.jsf + + + ThemeServlet + /theme/* + + + abc.jsf + + diff --git a/samples/DemoNBProject/web/abc.jsf b/samples/DemoNBProject/web/abc.jsf new file mode 100644 index 0000000..cd903f7 --- /dev/null +++ b/samples/DemoNBProject/web/abc.jsf @@ -0,0 +1,26 @@ + + + + +#include /header.inc + + "

     

    + + $pageSession{foo}); + /> + + "

    + + "

    + + + + +
    +#include /footer.inc +
    +
    +
    diff --git a/samples/DemoNBProject/web/before.jsf b/samples/DemoNBProject/web/before.jsf new file mode 100644 index 0000000..d9f544f --- /dev/null +++ b/samples/DemoNBProject/web/before.jsf @@ -0,0 +1,23 @@ + + + + + + "

     

    + + "You typed: #{in}, try typing: abc + + + "Type something and click 'Go!' + + + "Congratulations! You did it! + + "

    + + "

    + +
    +
    +
    +
    diff --git a/samples/DemoNBProject/web/footer.inc b/samples/DemoNBProject/web/footer.inc new file mode 100644 index 0000000..9d5bd41 --- /dev/null +++ b/samples/DemoNBProject/web/footer.inc @@ -0,0 +1,4 @@ + +"

     

    +"

    Copyright © Sun Microsystems, Inc. 2006

    +"
    diff --git a/samples/DemoNBProject/web/header.inc b/samples/DemoNBProject/web/header.inc new file mode 100644 index 0000000..7c1deb0 --- /dev/null +++ b/samples/DemoNBProject/web/header.inc @@ -0,0 +1,7 @@ +"
    \ + \ +

     

    Site Menu

    + +"
    \ +

    Welcome to the Test App!

    + diff --git a/samples/build.properties b/samples/build.properties new file mode 100644 index 0000000..f5d3871 --- /dev/null +++ b/samples/build.properties @@ -0,0 +1,81 @@ +## +## This is an example build.properties file, you should modify it to match +## your environment. It should be saved as file called "build.properties". +## +## NOTE to Windows Users: Use forward slashes (/) instead of back-slashes +## (\). For example: +## +## glassfish-home=C:/Sun/AppServer +## + + +## glassfish-home is the only variable you need to change if you are using +## GlassFish. glassfish-home is only used w/i this file, so if you don't have +## GlassFish, you only need to replace the references to GlassFish here. + +## Since the jar name is different depending on which version of Glassfish you are installed. You need to set glassfish-home and uncomment +## out one of the groups below. + +## *** GlassFish 3.1.0 *** , set the glassfish-home and uncomment out the .jar location below. +#glassfish-home=/GF-3.1.0/glassfish3/glassfish +#servlet-api.jar=${glassfish-home}/modules/javax.servlet.jar +#el-api.jar=${glassfish-home}/modules/javax.servlet.jsp.jar +#jsf-api.jar=${glassfish-home}/modules/jsf-api.jar + + +## *** Glassfish 3.1.1, 3.1.2 ***, set the glassfish-home here and uncomment out the .jar location below. +#glassfish-home=/GF-3.1.2/glassfish3/glassfish +servlet-api.jar=${glassfish-home}/modules/javax.servlet-api.jar +el-api.jar=${glassfish-home}/modules/javax.el-api.jar +jsf-api.jar=${glassfish-home}/modules/javax.faces.jar + +# gf 4.0 +servlet-api.jar=${glassfish-home}/modules/javax.servlet-api.jar +el-api.jar=${glassfish-home}/modules/javax.el.jar +jsf-api.jar=${glassfish-home}/modules/javax.faces.jar + +junit.jar=test/junit/junit.jar + +## You don't need to change these: +aptbuild=aptbuild +build=build +dist=dist +docs=docs +lib=lib +src=src/java +test=test + +jsft.jar=${dist}/jsft.jar +jsft-src.jar=${dist}/jsft-src.jar +jsftemplating.jar=${dist}/jsftemplating.jar +jsftemplating-base.jar=${dist}/jsftemplating-base.jar +jsftemplating-dt.jar=${dist}/jsftemplating-dt.jar +jsftemplating-src.jar=${dist}/jsftemplating-src.jar +jsftemplating-dt-src.jar=${dist}/jsftemplating-dt-src.jar +maven-repository-importer.jar=${lib}/external/maven-repository-importer-1.2.jar + +## bnd.jar +bnd.jar=lib/external/bnd-0.0.257.jar + +## User name under which to publish JSFTemplating artifacts to Maven +java.net.user.name= +javanettasks.jar=lib/external/javanettasks-1.0.12.jar +httpunit.jar=lib/external/httpunit-1.5.4.jar +nekohtml.jar=lib/external/nekohtml-0.9.5.jar +dom4j.jar=lib/external/dom4j-1.4.jar + +## Woodstock specific jar files +dataprovider.jar=lib/external/woodstock/dataprovider.jar + +jsftemplating.home=${src}/com/sun/jsftemplating + +source.version=1.6 +compile.debug=true +compile.optimize=true +compile.deprecation=false +compile.target=1.6 + +#proxy.host= +#proxy.port= +#proxy.user= +#proxy.pass= diff --git a/samples/build.xml b/samples/build.xml new file mode 100644 index 0000000..099c343 --- /dev/null +++ b/samples/build.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/samples/demo/Hello.jsp b/samples/demo/Hello.jsp new file mode 100644 index 0000000..980a0d5 --- /dev/null +++ b/samples/demo/Hello.jsp @@ -0,0 +1 @@ +Hello World! diff --git a/samples/demo/HelloWorld.jsf b/samples/demo/HelloWorld.jsf new file mode 100644 index 0000000..23bfe4f --- /dev/null +++ b/samples/demo/HelloWorld.jsf @@ -0,0 +1 @@ +"Hello World! diff --git a/samples/demo/WEB-INF/web.xml b/samples/demo/WEB-INF/web.xml new file mode 100644 index 0000000..8fb39bc --- /dev/null +++ b/samples/demo/WEB-INF/web.xml @@ -0,0 +1,42 @@ + + + + + com.sun.jsftemplating.DEBUG + true + + + ContentSources + org.example.contentSources.ExampleContentSource,org.example.contentSources.ProxyContentSource + + + FacesServlet + javax.faces.webapp.FacesServlet + + + javax.faces.LIFECYCLE_ID + com.sun.faces.lifecycle.PARTIAL + + 1 + + + ThemeServlet + com.sun.webui.theme.ThemeServlet + 2 + + + FacesServlet + /resource/* + + + FacesServlet + *.jsf + + + ThemeServlet + /theme/* + + + abc.jsf + + diff --git a/samples/demo/abc.jsf b/samples/demo/abc.jsf new file mode 100644 index 0000000..cd903f7 --- /dev/null +++ b/samples/demo/abc.jsf @@ -0,0 +1,26 @@ + + + + +#include /header.inc + + "

     

    + + $pageSession{foo}); + /> + + "

    + + "

    + + + + +
    +#include /footer.inc +
    +
    +
    diff --git a/samples/demo/aptbuild.xml b/samples/demo/aptbuild.xml new file mode 100644 index 0000000..c1f11a5 --- /dev/null +++ b/samples/demo/aptbuild.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/demo/before.jsf b/samples/demo/before.jsf new file mode 100644 index 0000000..d9f544f --- /dev/null +++ b/samples/demo/before.jsf @@ -0,0 +1,23 @@ + + + + + + "

     

    + + "You typed: #{in}, try typing: abc + + + "Type something and click 'Go!' + + + "Congratulations! You did it! + + "

    + + "

    + +
    +
    +
    +
    diff --git a/samples/demo/build.properties b/samples/demo/build.properties new file mode 100644 index 0000000..a2039e5 --- /dev/null +++ b/samples/demo/build.properties @@ -0,0 +1,56 @@ +## +## This is an example build.properties file, you should modify it to match +## your environment. +## + +## glassfish-home is only used w/i this file, you can alternatively just set +## the servlet-api.jar & jsf-api.jar files. +glassfish-home=/opt/SUNWappserver +servlet-api.jar=${glassfish-home}/lib/javaee.jar +## This is already available for GlassFish in javaee.jar +jsf-api.jar= +el-api.jar= + +## Location of the ant-apt target +ant-apt.jar=lib/ant-apt.jar + +## Location of jsftemplating.jar (need at compile time and runtime) +jsftemplating.jar=../dist/jsftemplating.jar + +## The "jsftemplating-dt.jar" is not required at runtime, it is needed at +## build-time +jsftemplating-dt.jar=../dist/jsftemplating-dt.jar + +## This jar file provides Dynamic Faces support for JSFTemplating. For more +## information on "Dynamic Faces", see the jsf-extensions web site: +## https://jsf-extensions.dev.java.net +jsftemplating-dynafaces.jar=../dist/jsftemplating-dynafaces.jar + +## The Project Woodstock component jar files and its dependencies. For more +## information on Project Woodstock, see the Woodstock web site: +## https://woodstock.dev.java.net +webui-jsf.jar=../lib/external/woodstock/webui-jsf.jar +webui-jsf-suntheme.jar=../lib/external/woodstock/webui-jsf-suntheme.jar +dataprovider.jar=../lib/external/woodstock/dataprovider.jar +json.jar=../lib/external/woodstock/json.jar +dojo.jar=../lib/external/woodstock/dojo-0.4.1-ajax.jar +dest-dojo.jar=WEB-INF/lib/dojo-0.4.1-ajax.jar +prototype.jar=../lib/external/woodstock/prototype-1.5.0.jar +dest-prototype.jar=WEB-INF/lib/prototype-1.5.0.jar + +## The name of the jar file to generate containing application specific classes +app.jar=WEB-INF/lib/app.jar + +## The name of the war file to generate +war.name=demo.war + +## Directories +build=build +javadoc=javadoc +src=src +docroot=. + +## Compiler flags +compile.debug=true +compile.optimize=false +compile.deprecation=false diff --git a/samples/demo/build.xml b/samples/demo/build.xml new file mode 100644 index 0000000..7c51ded --- /dev/null +++ b/samples/demo/build.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A 'Templating for JavaServer Faces Technology' application.]]> +
    https://jsftemplating.dev.java.net]]>
    + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/samples/demo/footer.inc b/samples/demo/footer.inc new file mode 100644 index 0000000..9d5bd41 --- /dev/null +++ b/samples/demo/footer.inc @@ -0,0 +1,4 @@ + +"

     

    +"

    Copyright © Sun Microsystems, Inc. 2006

    +"
    diff --git a/samples/demo/header.inc b/samples/demo/header.inc new file mode 100644 index 0000000..7c1deb0 --- /dev/null +++ b/samples/demo/header.inc @@ -0,0 +1,7 @@ +"
    \ + \ + ]]> + + +

     

    Site Menu

    + +"
    \ +

    Welcome to the Test App!

    + diff --git a/samples/demo/iftest.jsf b/samples/demo/iftest.jsf new file mode 100644 index 0000000..2a23619 --- /dev/null +++ b/samples/demo/iftest.jsf @@ -0,0 +1,806 @@ + + + + + + + if() test + + + + +

    Testing if's

    +

    The Test name will be appear the same color as the expected result + of the test. For example, Test1 looks + like that if the result of Test1 is + expected to be true. This lets you easily + check for evaluation errors.

    + +

    Variables:

    + +

    $pageSession{psTrue} == "true"
    + $pageSession{psFalse} == "false"
    + $pageSession{psELTrue} == "#{true}"
    + $pageSession{psELFalse} == "#{false}"
    + #{null} == (null)
    + #{requestScope.emptyString} == ""
    + #{requestScope.helloString} == "hello"
    + #{requestScope.zero} == 0
    + #{requestScope.thirteen} == 13
    + #{requestScope.minusNine} == -9
    +

    +
    + +"
    Test1: if (true): + + + + +"
    Test2: if (false): + + + + +"
    Test3: if (!true): + + + + +"
    Test4: if (!false): + + + + +"
    Test5: if (\#{true}): + + + + +"
    Test6: if (\#{false}): + + + + +"
    Test7: if (!\#{true}): + + + + +"
    Test8: if (!\#{false}): + + + + +"
    Test9: if ('\#{true}'): + + + + +"
    Test10: if ('\#{false}'): + + + + +"
    Test11: if ('!\#{true}'): + + + + +"
    Test12: if ('!\#{false}'): + + + + +// $pageSession{} tests... +"
    Test13: if ("\$pageSession{psTrue}"): + + + + +"
    Test14: if (\$pageSession{psTrue}): + + + + +"
    Test15: if ("!\$pageSession{psTrue}"): + + + + +"
    Test16: if (!\$pageSession{psTrue}): + + + + +"
    Test17: if ("\$pageSession{psFalse}"): + + + + +"
    Test18: if (\$pageSession{psFalse}): + + + + +"
    Test19: if ("!\$pageSession{psFalse}"): + + + + +"
    Test20: if (!\$pageSession{psFalse}): + + + + +"
    Test21: if ("\$pageSession{psELTrue}"): + + + + +"
    Test22: if (\$pageSession{psELTrue}): + + + + +"
    Test23: if ("!\$pageSession{psELTrue}"): + + + + +"
    Test24: if (!\$pageSession{psELTrue}): + + + + +"
    Test25: if ("\$pageSession{psELFalse}"): + + + + +"
    Test26: if (\$pageSession{psELFalse}): + + + + +"
    Test27: if ("!\$pageSession{psELFalse}"): + + + + +"
    Test28: if (!\$pageSession{psELFalse}): + + + + +"
    Test29: if ("\#{pageSession.psTrue}"): + + + + +"
    Test30: if (\#{pageSession.psTrue}): + + + + +"
    Test31: if ("!\#{pageSession.psTrue}"): + + + + +"
    Test32: if (!\#{pageSession.psTrue}): + + + + +"
    Test33: if ("\#{pageSession.psFalse}"): + + + + +"
    Test34: if (\#{pageSession.psFalse}): + + + + +"
    Test35: if ("!\#{pageSession.psFalse}"): + + + + +"
    Test36: if (!\#{pageSession.psFalse}): + + + + +"
    Test37: if ("\#{pageSession.psELTrue}"): + + + + +"
    Test38: if (\#{pageSession.psELTrue}): + + + + +"
    Test39: if ("!\#{pageSession.psELTrue}"): + + + + +"
    Test40: if (!\#{pageSession.psELTrue}): + + + + +"
    Test41: if ("\#{pageSession.psELFalse}"): + + + + +"
    Test42: if (\#{pageSession.psELFalse}): + + + + +"
    Test43: if ("!\#{pageSession.psELFalse}"): + + + + +"
    Test44: if (!\#{pageSession.psELFalse}): + + + + +"
    Test45: if (\#{requestScope.emptyString}): + + + + +"
    Test46: if (!\#{requestScope.emptyString}): + + + + +"
    Test47: if (\#{requestScope.helloString}): + + + + +"
    Test48: if (!\#{requestScope.helloString}): + + + + +"
    Test49: if (\#{requestScope.zero}): + + + + +"
    Test50: if (!\#{requestScope.zero}): + + + + +"
    Test51: if (\#{requestScope.thirteen}): + + + + +"
    Test52: if (!\#{requestScope.thirteen}): + + + + +"
    Test53: if (\#{requestScope.minusNine}): + + + + +"
    Test54: if (!\#{requestScope.minusNine}): + + + + +"
    Test55: if (\#{requestScope.minusNine}<\#{requestScope.zero}): + + + + +"
    Test56: if (\#{requestScope.minusNine}>\#{requestScope.zero}): + + #{requestScope.zero}) { + setAttribute(key="foo" value="true"); + } + /> + + +"
    Test57: if (\#{requestScope.minusNine}=\#{requestScope.zero}): + + + + +"
    Test58: if (\#{requestScope.minusNine}=\#{requestScope.minusNine}): + + + + +"
    Test59: if (\#{requestScope.nine}>\#{requestScope.thirteen}): + + #{requestScope.thirteen}) { + setAttribute(key="foo" value="true"); + } + /> + + +"
    Test60: if (\#{requestScope.nine}<\#{requestScope.thirteen}): + + + + +"
    Test61: if (\#{requestScope.hello}<\#{pageSession.psFalse}): +"Current impl does not support String comparison for '<' or '>', only integer. This would throw a NumberFormatException. + + +"
    Test62: if (\#{requestScope.hello}=\#{pageSession.psFalse}): + + + + +"
    Test63: if (\#{requestScope.hello}=\#{pageSession.hello}): + + + + +"
    Test64: if (\#{null}): + + + + +"
    Test65: if (!\#{null}): + + + + +"

    For the remaining tests, no test result means false + +"
    Test66: <!if \#{emptyString}>: + + + + +"
    Test67: <!if !\#{emptyString}>: + + + + +"
    Test68: <!if \#{helloString}>: + + + + +"
    Test69: <!if !\#{helloString}>: + + + + +"
    Test70: <!if !\#{null}>: + + + + +"
    Test71: <!if \#{null}>: + + + + +"
    Test72: <!if \#{pageSession.psELTrue}>: + + + + +"
    Test73: <!if !\#{pageSession.psELTrue}>: + + + + +"
    Test74: <!if \#{pageSession.psELFalse}>: + + + + +"
    Test75: <!if !\#{pageSession.psELFalse}>: + + + + +"
    Test76: <if condition="\#{pageSession.psELTrue}">: + + + + +"
    Test77: <if condition="!\#{pageSession.psELTrue}">: + + + + +"
    Test78: <if condition="\#{pageSession.psELFalse}">: + + + + +"
    Test79: <if condition="!\#{pageSession.psELFalse}">: + + + + +"

    The following tests are not valid b/c quotes (")'s are not supported by the <!if> component. The results are shown anyway, however. + +"
    Test80: <!if "\#{pageSession.psELTrue}">: + + + + +"
    Test81: <!if "!\#{pageSession.psELTrue}">: +"Current impl throws an exception b/c after ! operator is excuted values are left on the stack. + + +"
    Test82: <!if "\#{pageSession.psELFalse}">: + + + + +"
    Test83: <!if "!\#{pageSession.psELFalse}">: +"Current impl throws an exception b/c after ! operator is excuted values are left on the stack. + + + + + + diff --git a/samples/demo/src/MyBundle.properties b/samples/demo/src/MyBundle.properties new file mode 100644 index 0000000..6558f17 --- /dev/null +++ b/samples/demo/src/MyBundle.properties @@ -0,0 +1 @@ +welcome.msg=Welcome Message from MyBundle.properties file. diff --git a/samples/demo/src/org/example/contentSources/ExampleContentSource.java b/samples/demo/src/org/example/contentSources/ExampleContentSource.java new file mode 100644 index 0000000..d5dac83 --- /dev/null +++ b/samples/demo/src/org/example/contentSources/ExampleContentSource.java @@ -0,0 +1,111 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package org.example.contentSources; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; + +import com.sun.jsftemplating.util.fileStreamer.ContentSource; +import com.sun.jsftemplating.util.fileStreamer.Context; + + +/** + *

    This class implements ContentSource. It generates + * simple content to serve as a basic example for the + * FileStreamer functionality.

    + */ +public class ExampleContentSource implements ContentSource { + + /** + *

    This method returns a unique string used to identify this + * ContentSource. This string must be specified in + * order to select the appropriate {@link ContentSource} when using + * FileStreamer.

    + */ + public String getId() { + return ID; + } + + /** + *

    This method is responsible for generating the content and returning + * an InputStream for that content. It is also + * responsible for setting any attribute values in the + * Context, such as Context#EXTENSION or + * Context#CONTENT_TYPE.

    + */ + public InputStream getInputStream(Context ctx) throws IOException { + // See if we already have it. + InputStream in = (InputStream) ctx.getAttribute("inputStream"); + if (in == null) { + // Create some content... + in = new ByteArrayInputStream(("Hello! You requested: '" + + ctx.getAttribute(Context.FILE_PATH) + "'").getBytes()); + + // Set the extension so it can be mapped to a MIME type + ctx.setAttribute(Context.CONTENT_TYPE, "text/plain"); + + // Save in case method is called multiple times + ctx.setAttribute("inputStream", in); + } + + // Return the InputStream + return in; + } + + /** + *

    This method may be used to clean up any temporary resources. It + * will be invoked after the InputStream has been + * completely read.

    + */ + public void cleanUp(Context ctx) { + InputStream is = (InputStream) ctx.getAttribute("inputStream"); + + // Close the InputStream + if (is != null) { + try { + is.close(); + } catch (Exception ex) { + // Ignore... + } + } + ctx.removeAttribute("inputStream"); + } + + /** + *

    This method is responsible for returning the last modified date of + * the content, or -1 if not applicable. This information will be + * used for caching. (See ResourceContentSource for a + * better example.)

    + */ + public long getLastModified(Context context) { + // This will enable caching on all requests + return -1; + } + + /** + *

    This is the ID for this {@link ContentSource}.

    + */ + public static final String ID = "example"; +} diff --git a/samples/demo/src/org/example/contentSources/ProxyContentSource.java b/samples/demo/src/org/example/contentSources/ProxyContentSource.java new file mode 100644 index 0000000..90e2f83 --- /dev/null +++ b/samples/demo/src/org/example/contentSources/ProxyContentSource.java @@ -0,0 +1,131 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package org.example.contentSources; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Date; + +import com.sun.jsftemplating.util.fileStreamer.ContentSource; +import com.sun.jsftemplating.util.fileStreamer.Context; + + +/** + *

    This class implements ContentSource. It generates + * content by acting like a proxy. This is another example of + * FileStreamer functionality.

    + */ +public class ProxyContentSource implements ContentSource { + + /** + *

    This method returns a unique string used to identify this + * ContentSource. This string must be specified in + * order to select the appropriate {@link ContentSource} when using + * FileStreamer.

    + */ + public String getId() { + return ID; + } + + /** + *

    This method is responsible for getting the content and returning + * an InputStream for it. It is also responsible for + * setting any attribute values in the Context, such as + * Context#EXTENSION or + * Context#CONTENT_TYPE.

    + */ + public InputStream getInputStream(Context ctx) throws IOException { + // See if we already have it. + InputStream in = (InputStream) ctx.getAttribute("inputStream"); + if (in == null) { + // Get the path... + String path = (String) ctx.getAttribute(Context.FILE_PATH); + while (path.startsWith("/")) { + path = path.substring(1); + } + + // Get the URL... + URL url = new URL("http://" + path); + + // Set the extension so it can be mapped to a MIME type + int index = path.lastIndexOf('.'); + if (index > 0) { + ctx.setAttribute(Context.EXTENSION, path.substring(index + 1)); + } + + // Open the InputStream + in = url.openStream(); + + // Save in case method is called multiple times + ctx.setAttribute("inputStream", in); + } + + // Return an InputStream to the file + return in; + } + + /** + *

    This method may be used to clean up any temporary resources. It + * will be invoked after the InputStream has been + * completely read.

    + */ + public void cleanUp(Context ctx) { + // Get the File information + InputStream is = (InputStream) ctx.getAttribute("inputStream"); + + // Close the InputStream + if (is != null) { + try { + is.close(); + } catch (Exception ex) { + // Ignore... + } + } + ctx.removeAttribute("inputStream"); + } + + /** + *

    This method is responsible for returning the last modified date of + * the content, or -1 if not applicable. This information will be + * used for caching.

    + * + *

    This example will tell the browser to cache ALL content, regardless + * of changes in the content.

    + */ + public long getLastModified(Context context) { + // This will enable caching on all content + return DEFAULT_MODIFIED_DATE; + } + + /** + * This is the default "Last-Modified" Date. Its value is the + * Long representing the initialization time of this class. + */ + protected static final long DEFAULT_MODIFIED_DATE = (new Date()).getTime(); + + /** + *

    This is the ID for this {@link ContentSource}.

    + */ + public static final String ID = "proxy"; +} diff --git a/samples/demo/src/org/example/handlers/ExampleHandlers.java b/samples/demo/src/org/example/handlers/ExampleHandlers.java new file mode 100644 index 0000000..75d7fee --- /dev/null +++ b/samples/demo/src/org/example/handlers/ExampleHandlers.java @@ -0,0 +1,56 @@ +package org.example.handlers; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; + + +/** + *

    This class is written to demonstrate how to write a + * Handler.

    + */ +public class ExampleHandlers { + + /** + *

    This is a handler for the demo app. It contains 1 input and 1 + * output, both of type String. This handler will look at the input + * and produce a response to that input. It is looking for the input + * to equal 'abc', it provides the user a hint if they type something + * other than abc. If no input is provided, it prompts the user for + * input.

    + * + *

    Because handlers are defined via @annotations, you can move them + * to from one file or package to another without changing your pages + * that use the handlers. Also notice that this Handler has an "id" + * that is different from the method name. The "id" must be unique + * within the application. It is good practice to qualify all + * handlers to avoid a naming conflict.

    + * + * @param context The HandlerContext. + */ + @Handler(id="Test.getResponse", + input={ + @HandlerInput(name="userInput", type=String.class) + }, + output={ + @HandlerOutput(name="response", type=String.class) + }) + public static void calculateResponse(HandlerContext context) { + // Get the input. + String in = (String) context.getInputValue("userInput"); + + // Do business logic... + String resp = "Type something and click 'Go!'"; + if (in != null) { + if (in.equals("abc")) { + resp = "Congratulations, you did it!"; + } else if (!in.equals("")) { + resp = "You typed " + in + ", try typing 'abc'."; + } + } + + // Set the output. + context.setOutputValue("response", resp); + } +} diff --git a/samples/editor/build.properties b/samples/editor/build.properties new file mode 100644 index 0000000..2fdc76c --- /dev/null +++ b/samples/editor/build.properties @@ -0,0 +1,18 @@ + +## directories for building sample apps. +appname=editor.war +build.dir=build +classes.dir=${build.dir}/classes +assemble.dir=${build.dir}/assemble +src.web.dir=web +src.java.dir=src/java +src.conf.dir=src/conf +external.lib.dir=../../lib/external +external.lib.woodstock.dir=../../lib/external/woodstock +external.dist.dir=../../dist + +## jar files needed for runtime +dataprovider.jar=${external.lib.dir}/dataprovider.jar +defaulttheme.jar=${external.lib.dir}/defaulttheme.jar +webui.jar=${external.lib.dir}/webui.jar + diff --git a/samples/editor/build.xml b/samples/editor/build.xml new file mode 100644 index 0000000..5682004 --- /dev/null +++ b/samples/editor/build.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/editor/docs/index.html b/samples/editor/docs/index.html new file mode 100644 index 0000000..6e0d9c8 --- /dev/null +++ b/samples/editor/docs/index.html @@ -0,0 +1,35 @@ + + + + Simple Web Sample Application: Simple Web Sample Application + + + + + + + + + +
      sample editor 
    +
    Web Sample +Application : Editor +

    This document describes how to build the sample application: +Editor

    +
    +
    +
    + + diff --git a/samples/editor/src/conf/LocalStrings.properties b/samples/editor/src/conf/LocalStrings.properties new file mode 100644 index 0000000..60c32e9 --- /dev/null +++ b/samples/editor/src/conf/LocalStrings.properties @@ -0,0 +1,6 @@ +# $Id: LocalStrings.properties,v 1.1 2006-06-09 01:34:34 anilam Exp $ + +# Default localized resources for example servlets +# This locale is en_US + +helloworld.title=Hello World! diff --git a/samples/editor/src/java/com/sun/jsftemplating/samples/editor/Test.java b/samples/editor/src/java/com/sun/jsftemplating/samples/editor/Test.java new file mode 100644 index 0000000..03a2400 --- /dev/null +++ b/samples/editor/src/java/com/sun/jsftemplating/samples/editor/Test.java @@ -0,0 +1,47 @@ + +package com.sun.jsftemplating.samples.editor; + +import java.util.*; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; + +public class Test { + + /** Creates a new instance of Test */ + public Test() { + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + LayoutDefinition ld = LayoutDefinitionManager.getLayoutDefinition(null, "propSheet.jsf"); + + List compList = getList(ld, "", new ArrayList()); + + for (int i=0; i < compList.size(); i++) { + System.out.println(compList.get(i)); + } + + } + + + private static List getList(LayoutElement le, String indent, List newList) { + List list = le.getChildLayoutElements(); + + for (int i=0; i < list.size(); i++) { + LayoutElement lel = (LayoutElement)list.get(i); + if (lel instanceof LayoutComponent) { + newList.add(indent + lel.getUnevaluatedId()); + getList(lel, indent + " ", newList); + + } + } + + return newList; + } + +} + diff --git a/samples/editor/src/java/com/sun/jsftemplating/samples/editor/handlers/PageHandlers.java b/samples/editor/src/java/com/sun/jsftemplating/samples/editor/handlers/PageHandlers.java new file mode 100644 index 0000000..ffa1201 --- /dev/null +++ b/samples/editor/src/java/com/sun/jsftemplating/samples/editor/handlers/PageHandlers.java @@ -0,0 +1,273 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://jsftemplating.dev.java.net/cddl1.html or + * jsftemplating/cddl1.txt. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at jsftemplating/cddl1.txt. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ + +/* + * PageHandlers.java + * + * Created on June 9, 2006, 1:59 PM + * + * To change this template, choose Tools | Template Manager + * and open the template in the editor. + */ + +package com.sun.jsftemplating.samples.editor.handlers; + +import com.sun.jsftemplating.annotation.Handler; +import com.sun.jsftemplating.annotation.HandlerInput; +import com.sun.jsftemplating.annotation.HandlerOutput; +import com.sun.jsftemplating.layout.LayoutDefinitionException; +import com.sun.jsftemplating.layout.LayoutDefinitionManager; +import com.sun.jsftemplating.layout.descriptors.ComponentType; +import com.sun.jsftemplating.layout.descriptors.LayoutComponent; +import com.sun.jsftemplating.layout.descriptors.LayoutDefinition; +import com.sun.jsftemplating.layout.descriptors.LayoutElement; +import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext; +import com.sun.jsftemplating.layout.template.TemplateWriter; +import com.sun.jsftemplating.util.LayoutElementUtil; +import com.sun.jsftemplating.util.FileUtil; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import javax.faces.context.FacesContext; + + +/** + * + * @author Administrator + */ +public class PageHandlers { + + /** + * Creates a new instance of PageHandlers + */ + public PageHandlers() { + } + + /** + *

    + *

    + * + *
    • pageName --
    • + *
    • parent --
    • + *
    • type --
    • + *
    • id --
    • + *
    • label --
    • + *
    • text --
    • + *
    • nvps --
    + * + */ + @Handler(id="addLayoutComponentToPage", + input={ + @HandlerInput(name="pageName", type=String.class, required=true), + @HandlerInput(name="parent", type=String.class, required=true), + @HandlerInput(name="type", type=String.class, required=true), + @HandlerInput(name="id", type=String.class, required=false), + @HandlerInput(name="label", type=String.class, required=false), + @HandlerInput(name="text", type=String.class, required=false), + @HandlerInput(name="nvps", type=Iterator.class, required=false) + }, + output={ + @HandlerOutput(name="newComponent", type=LayoutComponent.class) + }) + public static void addLayoutComponentToPage(HandlerContext context) { + FacesContext facesCtx = context.getFacesContext(); + // Get Page + String pageName = (String) context.getInputValue("pageName"); + LayoutDefinition ld = LayoutDefinitionManager.getLayoutDefinition( + facesCtx, pageName); + + // Walk the LD + LayoutElement parent = ld; + String id = (String) context.getInputValue("parent"); + if (id == null) { +// FIXME: report an error? + return; + } + StringTokenizer tok = new StringTokenizer(id, ":"); + while (tok.hasMoreTokens()) { + id = tok.nextToken(); + parent = parent.getChildLayoutElement(id); + if (parent == null) { + throw new IllegalArgumentException("LayoutElement '" + id + + "' not found when attempting to resolve " + + "LayoutElement identified by '" + parent + "'"); + } + } + + // Create the new LayoutComponent + ComponentType type = LayoutDefinitionManager.getGlobalComponentType( + facesCtx, (String) context.getInputValue("type")); + if (type == null) { + throw new IllegalArgumentException("Unkown ComponentType: " + + context.getInputValue("type")); + } + id = (String) context.getInputValue("id"); + if (id == null) { + id = LayoutElementUtil.getGeneratedId(null); + } + LayoutComponent comp = new LayoutComponent(parent, id, type); + comp.setNested(true); + //checkForFacetChild + + // Add properties to it.... + String value = (String) context.getInputValue("label"); + if (value != null) { + comp.addOption("label", value); + } + value = (String) context.getInputValue("text"); + if (value != null) { + comp.addOption("text", value); + } + int idx = 0; + String name = null; + Iterator it = (Iterator) context.getInputValue("nvps"); + if (it != null) { + while (it.hasNext()) { + value = it.next(); + idx = value.indexOf('='); + if (idx == -1) { + throw new IllegalArgumentException("Invalid NVP: '" + value + + "'. It must be of the form 'name=value'!"); + } + name = value.substring(0, idx).trim(); + value = value.substring(idx + 1).trim(); + comp.addOption(name, value); + } + } + + // Add the component to the parent... + parent.addChildLayoutElement(comp); + + // Write out the page w/ the changes... + writePage(facesCtx.getExternalContext().getContext(), pageName, ld); + + // Return the new component + context.setOutputValue("newComponent", comp); + } + + /** + *

    This handler returns a list of display names and the corresponding + * list of qualified names of all the LayoutComponents in a given page.

    + * + *

    Input value: "pageName" -- Type: java.lang.String

    + * + *

    Output value: "displayNames" -- Type: java.util.List

    + * + *

    Output value: "qualifiedNames" -- Type: java.util.List

    + * @param context The HandlerContext. + */ + @Handler(id="getPageComponentNames", + input={ + @HandlerInput(name="pageName", type=String.class, required=true)}, + output={ + @HandlerOutput(name="displayNames", type=List.class), + @HandlerOutput(name="qualifiedNames", type=List.class)}) + public static void getPageComponentNames(HandlerContext context) { + String pageName = (String) context.getInputValue("pageName"); + LayoutDefinition ld = null; + FacesContext facesCtx = context.getFacesContext(); + try { + ld = LayoutDefinitionManager.getLayoutDefinition( + facesCtx, pageName); + } catch (LayoutDefinitionException ex) { + // New page + ld = LayoutDefinitionManager.getLayoutDefinition( + facesCtx, "template.jsf"); +// FIXME... must *clone* this tree... or read it directly from the Reader instead of through the Manager + LayoutDefinitionManager.putCachedLayoutDefinition(facesCtx, pageName, ld); + // Write it to disk... + writePage(facesCtx.getExternalContext().getContext(), pageName, ld); + } + List displayNames = getDisplayList(ld, new ArrayList(), ""); + List qualifiedNames = getQualifiedList(ld, new ArrayList(), ""); + context.setOutputValue("displayNames", displayNames); + context.setOutputValue("qualifiedNames", qualifiedNames); + } + + /** + *

    This method takes in the name of a page and writes the given + * LayoutDefinition to the docroot. The + * context passed in must be a + * ServletContext or PortletContext.

    + */ + private static void writePage(Object context, String pageName, LayoutDefinition ld) { + String path = FileUtil.getRealPath(context, pageName); + if (path == null) { + throw new IllegalArgumentException( + "Unable to determine where to write '" + pageName + + "'! Is this application is directory deployed?"); + } + try { + OutputStream os = new FileOutputStream(path); + new TemplateWriter(os).write(ld); + os.close(); + } catch (FileNotFoundException ex2) { + throw new IllegalArgumentException("Unable to write '" + path + + "'! Is this application is directory deployed and " + + "the directory is writable?", ex2); + } catch (IOException ex2) { + throw new RuntimeException(ex2); + } + } + + private static List getDisplayList(LayoutElement le, List displayList, String indent) { + Formatter printf = null; + List list = le.getChildLayoutElements(); + for (int i=0; i < list.size(); i++) { + LayoutElement lel = (LayoutElement)list.get(i); + if (lel instanceof LayoutComponent) { + printf = new Formatter(); + printf.format("%-25s", + ((LayoutComponent) lel).getType().getId()); + displayList.add(printf.toString().replaceAll(" ", " ") + indent + lel.getUnevaluatedId()); + getDisplayList(lel, displayList, indent + " "); + } + } + + return displayList; + } + + private static List getQualifiedList(LayoutElement le, List qualifiedList, String longName) { + List list = le.getChildLayoutElements(); + + for (int i=0; i < list.size(); i++) { + LayoutElement lel = (LayoutElement)list.get(i); + if (lel instanceof LayoutComponent) { + qualifiedList.add(longName + lel.getUnevaluatedId()); + getQualifiedList(lel, qualifiedList, longName + lel.getUnevaluatedId() + ":"); + } + } + + return qualifiedList; + } + + +} diff --git a/samples/editor/web/WEB-INF/web.xml b/samples/editor/web/WEB-INF/web.xml new file mode 100644 index 0000000..7011508 --- /dev/null +++ b/samples/editor/web/WEB-INF/web.xml @@ -0,0 +1,42 @@ + + + + + javax.faces.STATE_SAVING_METHOD + client + + + + com.sun.jsftemplating.DEBUG + true + + + + com.sun.webui.jsf.DEFAULT_THEME + suntheme + + + FacesServlet + javax.faces.webapp.FacesServlet + 1 + + + ThemeServlet + com.sun.webui.theme.ThemeServlet + 2 + + + FacesServlet + *.jsf + + + ThemeServlet + /theme/* + + + + jsfToolStep1.jsf + + + + diff --git a/samples/editor/web/jsfToolStep1.jsf b/samples/editor/web/jsfToolStep1.jsf new file mode 100644 index 0000000..b4e93da --- /dev/null +++ b/samples/editor/web/jsfToolStep1.jsf @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + $attribute{pageName}); + getUIComponentProperty(component="$attribute{pageName}", name="value", value=>$attribute{pagename}); + navigate(page="/jsfToolStep2.jsf"); + /> + + + + "

    +
    +
    +
    +
    +
    +
    diff --git a/samples/editor/web/jsfToolStep2.jsf b/samples/editor/web/jsfToolStep2.jsf new file mode 100644 index 0000000..6902c05 --- /dev/null +++ b/samples/editor/web/jsfToolStep2.jsf @@ -0,0 +1,107 @@ + + + + " + + + + + + + + + + + + + + + + + + $attribute{disp} qualifiedNames=>$attribute{long}); + getSunOptions(labels="$attribute{disp}", values="$attribute{long}", options=>$attribute{opts}); + + /> + + + + + + + $attribute{ids}); + getSunOptions(labels="$attribute{ids}", values="$attribute{ids}", options=>$attribute{types}); + /> + + "
    + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + "

    + +
    + +
    + + + + + + + + + +
    +
    +
    +
    diff --git a/samples/editor/web/template.jsf b/samples/editor/web/template.jsf new file mode 100644 index 0000000..0ca0b51 --- /dev/null +++ b/samples/editor/web/template.jsf @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/samples/eventdemo/WEB-INF/faces-config.xml b/samples/eventdemo/WEB-INF/faces-config.xml new file mode 100644 index 0000000..f711d93 --- /dev/null +++ b/samples/eventdemo/WEB-INF/faces-config.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/samples/eventdemo/WEB-INF/lib/jsft.jar b/samples/eventdemo/WEB-INF/lib/jsft.jar new file mode 100644 index 0000000..b4a772f Binary files /dev/null and b/samples/eventdemo/WEB-INF/lib/jsft.jar differ diff --git a/samples/eventdemo/WEB-INF/web.xml b/samples/eventdemo/WEB-INF/web.xml new file mode 100644 index 0000000..772eaea --- /dev/null +++ b/samples/eventdemo/WEB-INF/web.xml @@ -0,0 +1,51 @@ + + + + + com.sun.jsftemplating.DEBUG + true + + + javax.faces.VALIDATE_EMPTY_FIELDS + false + + + javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR + false + + + javax.faces.PROJECT_STAGE + + Development + + + + javax.faces.FACELETS_SKIP_COMMENTS + true + + + + FacesServlet + javax.faces.webapp.FacesServlet + 1 + + + FacesServlet + *.xhtml + + + FacesServlet + *.jsf + + + index.jsf + + + javax.faces.application.ViewExpiredException + / + + + diff --git a/samples/eventdemo/deferredFragment.xhtml b/samples/eventdemo/deferredFragment.xhtml new file mode 100644 index 0000000..24bcbd1 --- /dev/null +++ b/samples/eventdemo/deferredFragment.xhtml @@ -0,0 +1,46 @@ + + + + + + + + +test + + + +
    + + + println("######## HERE: ".concat(component.children)); + + +
    +
    + Hello World!
    + +
    +
    +
    + +
    + + And something else goes here.
    + The component clientId = #{component.getClientId()} +
    +
    + +
    + + + +
    +
    + diff --git a/samples/eventdemo/index.xhtml b/samples/eventdemo/index.xhtml new file mode 100644 index 0000000..d9a7ee7 --- /dev/null +++ b/samples/eventdemo/index.xhtml @@ -0,0 +1,46 @@ + + + + + + + + println('preRenderComponent'); + + + + + + + + + + + + diff --git a/samples/eventdemo/loop.xhtml b/samples/eventdemo/loop.xhtml new file mode 100644 index 0000000..29815ba --- /dev/null +++ b/samples/eventdemo/loop.xhtml @@ -0,0 +1,29 @@ + + + + + + + + foreach("item", component.children) { + // Note: You can't use util.write() because the response writer + // Note: is not accessible yet. + util.println(item.id); + } + + + + + + + + + + + diff --git a/samples/facelets/WebRoot/WEB-INF/faces-config.xml b/samples/facelets/WebRoot/WEB-INF/faces-config.xml new file mode 100644 index 0000000..89d1cf1 --- /dev/null +++ b/samples/facelets/WebRoot/WEB-INF/faces-config.xml @@ -0,0 +1,12 @@ + + + + + + com.sun.facelets.FaceletViewHandler + + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/WEB-INF/web.xml b/samples/facelets/WebRoot/WEB-INF/web.xml new file mode 100644 index 0000000..e52884f --- /dev/null +++ b/samples/facelets/WebRoot/WEB-INF/web.xml @@ -0,0 +1,46 @@ + + + + com.sun.faces.verifyObjects + false + + + javax.faces.DEFAULT_SUFFIX + .xhtml + + + com.sun.jsftemplating.DEBUG + true + + + facelets.DEVELOPMENT + true + + + facelets.VIEW_MAPPINGS + *.flt;*.xhtml + + + com.sun.jsftemplating.VIEW_MAPPINGS + *.jsf + + + + Faces Servlet + javax.faces.webapp.FacesServlet + 1 + + + Faces Servlet + *.flt + + + Faces Servlet + *.jsf + + + + index.html + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/composition.xhtml b/samples/facelets/WebRoot/composition.xhtml new file mode 100644 index 0000000..ea62e09 --- /dev/null +++ b/samples/facelets/WebRoot/composition.xhtml @@ -0,0 +1,24 @@ + + + + Here is some text outside the the ui:composition that will not be rendered. +
    + + + This is ui:define#foo in a ui:composition. This will be rendered on the client. +
    +
    + This text will also *not* be rendered on the client. +
    + + Nor will this text. If you're seeing this, we have a bug! :) +
    +
    +
    + Here is some more text outside the the ui:composition that will not be rendered. +
    + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/decorate.xhtml b/samples/facelets/WebRoot/decorate.xhtml new file mode 100644 index 0000000..13d0b36 --- /dev/null +++ b/samples/facelets/WebRoot/decorate.xhtml @@ -0,0 +1,24 @@ + + + + Here is some text outside the the ui:decorate that will be rendered. +
    + + + This is ui:define#foo2 in a ui:decorate. This will be rendered on the client. +
    +
    + This text will *not* be rendered on the client. +
    + + Nor will this text. If you're seeing this, we have a bug! :) +
    +
    +
    + Here is some more text outside the the ui:decorate that will be rendered. +
    + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/e_define1.xhtml b/samples/facelets/WebRoot/e_define1.xhtml new file mode 100644 index 0000000..68d2b38 --- /dev/null +++ b/samples/facelets/WebRoot/e_define1.xhtml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/e_define2.xhtml b/samples/facelets/WebRoot/e_define2.xhtml new file mode 100644 index 0000000..cd30c80 --- /dev/null +++ b/samples/facelets/WebRoot/e_define2.xhtml @@ -0,0 +1,20 @@ + + + + + + foo3: defined in e_define2.xhtml + + + + no foo3 defined + + + + + + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/e_define2b.xhtml b/samples/facelets/WebRoot/e_define2b.xhtml new file mode 100644 index 0000000..35fc94c --- /dev/null +++ b/samples/facelets/WebRoot/e_define2b.xhtml @@ -0,0 +1,13 @@ + + + + + + foo3: defined in e_define2b.xhtml + + + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/e_defineTemplate.xhtml b/samples/facelets/WebRoot/e_defineTemplate.xhtml new file mode 100644 index 0000000..5182f03 --- /dev/null +++ b/samples/facelets/WebRoot/e_defineTemplate.xhtml @@ -0,0 +1,22 @@ + + + + + foo3 defined in e_defineTemplate.xhtml + +
    + + foo2 is not defined! + +
    + + + + \ No newline at end of file diff --git a/samples/facelets/WebRoot/index.html b/samples/facelets/WebRoot/index.html new file mode 100644 index 0000000..c7d46f9 --- /dev/null +++ b/samples/facelets/WebRoot/index.html @@ -0,0 +1,77 @@ + + + +JSFT-Facelets <-> Facelets + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    JSFT-Facelets <-> Facelets
    JSFT [*.jsf]Facelets [*.flt] 
    CompositionCompositionDemonstrates the use of <ui:composition>
    DecorateDecorateDemonstrates the use of <ui:decorate>
    Incompatibility Testcases
    Define1Define1Demonstrates a incompatibility if a ui:define contains an + ui:insert with the same name
    Define2Define2Demonstrates content rendered in jsft that is not rendered + in facelets + usage of the "wrong" define
    + + diff --git a/samples/facelets/WebRoot/simpleTemplate.xhtml b/samples/facelets/WebRoot/simpleTemplate.xhtml new file mode 100644 index 0000000..91b62af --- /dev/null +++ b/samples/facelets/WebRoot/simpleTemplate.xhtml @@ -0,0 +1,23 @@ + + + + This is a test. +
    + Facelets will render this literally, giving you some EL on your page, while JSFTemplating + will evaluate it an emit a client ID: +
    + +
    + + Here is some text in the template that will be rendered after the defined block "foo2" is rendered. +
    + + + + \ No newline at end of file diff --git a/samples/facelets/build.xml b/samples/facelets/build.xml new file mode 100644 index 0000000..261dbd0 --- /dev/null +++ b/samples/facelets/build.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/lib/README.txt b/samples/lib/README.txt new file mode 100644 index 0000000..04a6a05 --- /dev/null +++ b/samples/lib/README.txt @@ -0,0 +1,8 @@ + +This directory (samples/lib) should have the following 3 jars: +webui.jar +defaulttheme.jar +dataprovider.jar + +A copy of these jars can be obtained from your creator installation. + diff --git a/samples/woodstock/README b/samples/woodstock/README new file mode 100644 index 0000000..09a91bc --- /dev/null +++ b/samples/woodstock/README @@ -0,0 +1,7 @@ + +* Edit the build.properties files and change properties as necessary. + +* Type 'ant' to build. + +* The 'example' folder will be deployable in GlassFish. You may need extra jar + files for non-Java EE 5 containers. diff --git a/samples/woodstock/build.properties b/samples/woodstock/build.properties new file mode 100644 index 0000000..8214181 --- /dev/null +++ b/samples/woodstock/build.properties @@ -0,0 +1,62 @@ +## +## This is an example build.properties file, you should modify it to match +## your environment. +## + +## glassfish-home is only used w/i this file, you can alternatively just set +## the servlet-api.jar & jsf-api.jar files. +#glassfish-home=/opt/SUNWappserver + +glassfish-home=/opt/glassfish +servlet-api.jar=${glassfish-home}/lib/javaee.jar +## This is already available for GlassFish in javaee.jar +jsf-api.jar= +el-api.jar= + +## Location of the ant-apt target +ant-apt.jar=../../lib/external/ant-apt.jar + +## Location of jsftemplating.jar (need at compile time and runtime) +jsftemplating.jar=../../dist/jsftemplating.jar + +## The "jsftemplating-dt.jar" is not required at runtime, it is needed at +## build-time +jsftemplating-dt.jar=../../dist/jsftemplating-dt.jar + +## This jar file provides Dynamic Faces support for JSFTemplating. For more +## information on "Dynamic Faces", see the jsf-extensions web site: +## https://jsf-extensions.dev.java.net +jsftemplating-dynafaces.jar=../../dist/jsftemplating-dynafaces-0.1.jar + +## The WEB-INF/lib directory +WEB-INF_lib=example/WEB-INF/lib + +## The Project Woodstock component jar files and its dependencies. For more +## information on Project Woodstock, see the Woodstock web site: +## https://woodstock.dev.java.net +webui-jsf.jar=../../lib/external/woodstock/webui-jsf.jar +webui-jsf-suntheme.jar=../../lib/external/woodstock/webui-jsf-suntheme.jar +dataprovider.jar=../../lib/external/woodstock/dataprovider.jar +json.jar=../../lib/external/woodstock/json.jar +dojo.jar=../../lib/external/woodstock/dojo-0.4.1-ajax.jar +dest-dojo.jar=${WEB-INF_lib}/dojo-0.4.1-ajax.jar +prototype.jar=../../lib/external/woodstock/prototype-1.5.0.jar +dest-prototype.jar=${WEB-INF_lib}/prototype-1.5.0.jar + +## The name of the jar file to generate containing application specific classes +app.jar=${WEB-INF_lib}/app.jar +app-src.jar=${WEB-INF_lib}/app-src.jar + +## The name of the war file to generate +war.name=woodstock.war + +## Directories +build=build +javadoc=javadoc +src=src +docroot=example + +## Compiler flags +compile.debug=true +compile.optimize=false +compile.deprecation=false diff --git a/samples/woodstock/build.xml b/samples/woodstock/build.xml new file mode 100644 index 0000000..733442f --- /dev/null +++ b/samples/woodstock/build.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A 'Templating for JavaServer Faces Technology' application.]]> +
    https://jsftemplating.dev.java.net]]>
    + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/samples/woodstock/example/ShowCode.jsf b/samples/woodstock/example/ShowCode.jsf new file mode 100644 index 0000000..2c66e8a --- /dev/null +++ b/samples/woodstock/example/ShowCode.jsf @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + +"

    +"
    +"
    +"
              
    +		            
    +		                         
    +"		
    +"
    +"
    +"

    +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/WEB-INF/faces-config.xml b/samples/woodstock/example/WEB-INF/faces-config.xml new file mode 100644 index 0000000..f766ebc --- /dev/null +++ b/samples/woodstock/example/WEB-INF/faces-config.xml @@ -0,0 +1,748 @@ + + + + + + + + + en + de + fr + zh_TW + + + + + com.sun.webui.jsf.example.statictext.Employee + com.sun.webui.jsf.example.statictext.EmployeeConverter + + + + dirValidator + com.sun.webui.jsf.example.chooseruploader.ChooserUploaderValidator + + + + The backing bean for the index page + IndexBean + com.sun.webui.jsf.example.index.IndexBackingBean + session + + + + The backing bean for the show code page + ShowCodeBean + com.sun.webui.jsf.example.index.ShowCodeBackingBean + session + + + + The backing bean for the button example + ButtonBean + com.sun.webui.jsf.example.button.ButtonBackingBean + session + + + + The backing bean for the label example + LabelBean + com.sun.webui.jsf.example.label.LabelBackingBean + session + + + + The backing bean for the inline alert example + InlineAlertBean + com.sun.webui.jsf.example.alert.InlineAlertBackingBean + session + + + + The backing bean for the page alert example + PageAlertBean + com.sun.webui.jsf.example.alert.PageAlertBackingBean + session + + + + The backing bean for the checkbox and radiobutton example + CheckboxRadiobuttonBean + com.sun.webui.jsf.example.cbrb.CheckboxRadiobuttonBackingBean + session + + + + The backing bean for the text input example + TextInputBean + com.sun.webui.jsf.example.field.TextInputBackingBean + session + + + + The backing bean for the add remove example + AddRemoveBean + com.sun.webui.jsf.example.addremove.AddRemoveBackingBean + session + + + + The backing bean for the table example + TableBean + com.sun.webui.jsf.example.table.TableBean + session + + + + The backing bean for the dynamic group table example + DynamicGroupTableBean + com.sun.webui.jsf.example.table.DynamicGroupTableBean + session + + + + The backing bean for the dynamic table example + DynamicTableBean + com.sun.webui.jsf.example.table.DynamicTableBean + session + + + + The backing bean for the orderable list example + OrderableListBean + com.sun.webui.jsf.example.orderablelist.OrderableListBackingBean + session + + + + The backing bean for the file/folder chooser and file uploader + ChooserUploaderBean + com.sun.webui.jsf.example.chooseruploader.ChooserUploaderBackingBean + session + + + + The backing bean for the file chooser + FileChooserBean + com.sun.webui.jsf.example.chooseruploader.FileChooserBackingBean + session + + + + The backing bean for the folder chooser + FolderChooserBean + com.sun.webui.jsf.example.chooseruploader.FolderChooserBackingBean + session + + + + The backing bean for the file uploader + FileUploaderBean + com.sun.webui.jsf.example.chooseruploader.FileUploaderBackingBean + session + + + + The backing bean for the menu and list example + MenuListBean + com.sun.webui.jsf.example.menu.MenuListBackingBean + session + + + + The backing bean for the Image and Masthead example + MastheadBean + com.sun.webui.jsf.example.masthead.MastheadBackingBean + session + + + + The backing bean for the Property Sheet + PropertySheetBean + com.sun.webui.jsf.example.propertysheet.PropertySheetBackingBean + session + + + + The backing bean for the Editable List + EditableListBean + com.sun.webui.jsf.example.editablelist.EditableListBackingBean + session + + + + The backing bean for the Content Page Title example + PagetitleBean + com.sun.webui.jsf.example.pagetitle.PagetitleBackingBean + session + + + + The backing bean for the Hyperlink + HyperlinkBean + com.sun.webui.jsf.example.hyperlink.HyperlinkBackingBean + session + + + + The backing bean for the Static Text example + StatictextBean + com.sun.webui.jsf.example.statictext.StatictextBackingBean + session + + + + The backing bean for the Common Tasks Section example + commonTask + com.sun.webui.jsf.example.commontask.commonTaskBean + request + + + + The backing bean for the dynamic tree example + DynamicTreeBean + com.sun.webui.jsf.example.tree.DynamicTreeBackingBean + session + + + + The backing bean for the navigation tree example + NavTreeBean + com.sun.webui.jsf.example.tree.NavTreeBackingBean + session + + + + The backing bean for the ProgressBar example + ProgressBarBean + com.sun.webui.jsf.example.progressbar.ProgressBarBackingBean + session + + + + The backing bean for the simple Wizard example + SimpleWizardBean + com.sun.webui.jsf.example.wizard.SimpleWizardBackingBean + session + + + + /* + + + + showCode + /ShowCode.jsf + + + + + + showIndex + /index.jsf + + + + + + showAlertIndex + /alert/Alert.jsf + + + + + showInlineAlert + /alert/InlineAlert.jsf + + + + + showPageAlert + /alert/PageAlert.jsf + + + + + showPageAlertExample + /alert/PageAlertExample.jsf + + + + + + showTextInput + /field/TextInput.jsf + + + + + showTextInputResults + /field/TextInputResults.jsf + + + + + + showAddRemove + /addremove/AddRemove.jsf + + + + + showAddRemoveResults + /addremove/AddRemoveResults.jsf + + + + + + showTableIndex + /table/index.jsf + + + + + + showOrderableList + /orderablelist/OrderableList.jsf + + + + + showOrderableListResults + /orderablelist/OrderableListResults.jsf + + + + + + showChooserUploader + /chooseruploader/index.jsf + + + + + + fileChooser + /chooseruploader/fileChooser.jsf + + + + + + folderChooser + /chooseruploader/folderChooser.jsf + + + + + + fileUploader + /chooseruploader/fileUploader.jsf + + + + + + fileChooserUploader + /chooseruploader/fileUploaderPopup.jsf + + + + + + showMenuList + /menu/MenuList.jsf + + + + + showMenuListResults + /menu/MenuListResults.jsf + + + + + + showPropertySheet + /propertysheet/PropertySheet.jsf + + + + + + showPropertySheetResult + /propertysheet/PropertySheetResult.jsf + + + + + + showEditableList + /editablelist/editableList.jsf + + + + + + showEditableListResult + /editablelist/editableListResult.jsf + + + + + + showHyperlink + /hyperlink/hyperLink.jsf + + + + + + resultHyperlink + /hyperlink/hyperLinkResult.jsf + + + + + + showButton + /button/Button.jsf + + + + + showButtonResults + /button/ButtonResults.jsf + + + + + + showLabel + /label/Label.jsf + + + + + showLabelResults + /label/LabelResults.jsf + + + + + + showCheckboxRadiobutton + /cbrb/checkboxRadiobutton.jsf + + + + + showCBRBResults + /cbrb/checkboxRadiobuttonResults.jsf + + + + + + showTreeIndex + /tree/index.jsf + + + + + showDynamicTree + /tree/dynamicTree.jsf + + + + + showNavTree + /tree/navTree.jsf + + + + + + + + /table/* + + + showTableMain + /table/table.jsf + + + + + showTableActions + /table/actions.jsf + + + + + showTableAlarms + /table/alarms.jsf + + + + + showTableBasic + /table/basicTable.jsf + + + + + showTableCustomTitle + /table/customTitle.jsf + + + + + showTableDynamicGroupTable + /table/dynamicGroupTable.jsf + + + + + showTableDynamicTable + /table/dynamicTable.jsf + + + + + showTableEmbeddedActions + /table/embeddedActions.jsf + + + + + showTableEmptyCells + /table/emptyCells.jsf + + + + + showTableFilter + /table/filter.jsf + + + + + showTableGroupTable + /table/groupTable.jsf + + + + + showTableHiddenSelectedRows + /table/hiddenSelectedRows.jsf + + + + + showTableMultiHeadersFooters + /table/multipleHeadersFooters.jsf + + + + + showTableLiteTable + /table/liteTable.jsf + + + + + showTablePaginatedTable + /table/paginatedTable.jsf + + + + + showTablePreferences + /table/preferences.jsf + + + + + showTableSelectMultiRows + /table/selectMultipleRows.jsf + + + + + showTableSelectSingleRow + /table/selectSingleRow.jsf + + + + + showTableSpacerColumn + /table/spacerColumn.jsf + + + + + showTableSortableTable + /table/sortableTable.jsf + + + + + + /index.jsf + + + + showButton + /button/Button.jsf + + + + + + showLabel + /label/Label.jsf + + + + + + showCheckboxRadiobutton + /cbrb/checkboxRadiobutton.jsf + + + + + + showMasthead + /masthead/Index.jsf + + + + + + showPagetitle + /pagetitle/Pagetitle.jsf + + + + + + showStaticText + /statictext/Statictext.jsf + + + + + + + + /masthead/* + + + showMasthead1 + /masthead/Masthead.jsf + + + + + showMasthead2 + /masthead/MastheadFacets.jsf + + + + + showMasthead3 + /masthead/Images.jsf + + + + + showResultMasthead + /masthead/ResultMasthead.jsf + + + + + showResultMastheadFacets + /masthead/ResultMastheadFacets.jsf + + + + + showMasthead + /masthead/Index.jsf + + + + + + + + task + /commontask/sample.jsf + + + + showCommonTask + /commontask/commonTasks.jsf + + + + + + + showProgressBar + /progressbar/index.jsf + + + + showDeterminate + /progressbar/determinate.jsf + + + + showIndeterminate + /progressbar/indeterminate.jsf + + + + showBusy + /progressbar/busy.jsf + + + + + + + showWizardIndex + /wizard/index.jsf + + + + + diff --git a/samples/woodstock/example/WEB-INF/lib/commons-fileupload-1.0.jar b/samples/woodstock/example/WEB-INF/lib/commons-fileupload-1.0.jar new file mode 100644 index 0000000..1ca4a9c Binary files /dev/null and b/samples/woodstock/example/WEB-INF/lib/commons-fileupload-1.0.jar differ diff --git a/samples/woodstock/example/WEB-INF/web.xml b/samples/woodstock/example/WEB-INF/web.xml new file mode 100644 index 0000000..2583f23 --- /dev/null +++ b/samples/woodstock/example/WEB-INF/web.xml @@ -0,0 +1,104 @@ + + + + + + javax.faces.STATE_SAVING_METHOD + server + + + + com.sun.jsftemplating.DEBUG + true + + + + com.sun.webui.jsf.DEFAULT_THEME + suntheme + + + + + UploadFilter + com.sun.webui.jsf.util.UploadFilter + + maxSize + 1000000 + + + sizeThreshold + 4096 + + + + + + UploadFilter + FacesServlet + + + + + FacesServlet + javax.faces.webapp.FacesServlet + + javax.faces.LIFECYCLE_ID + com.sun.faces.lifecycle.PARTIAL + + 1 + + + + + ThemeServlet + com.sun.webui.theme.ThemeServlet + 2 + + + + + FacesServlet + /faces/* + + + + + ThemeServlet + /theme/* + + + + 30 + + + + + index.jsp + index.html + index.htm + + diff --git a/samples/woodstock/example/addremove/AddRemove.jsf b/samples/woodstock/example/addremove/AddRemove.jsf new file mode 100644 index 0000000..66c54b8 --- /dev/null +++ b/samples/woodstock/example/addremove/AddRemove.jsf @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/addremove/AddRemoveResults.jsf b/samples/woodstock/example/addremove/AddRemoveResults.jsf new file mode 100644 index 0000000..f1a6ee7 --- /dev/null +++ b/samples/woodstock/example/addremove/AddRemoveResults.jsf @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/alert/Alert.jsf b/samples/woodstock/example/alert/Alert.jsf new file mode 100644 index 0000000..8b6b2af --- /dev/null +++ b/samples/woodstock/example/alert/Alert.jsf @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/alert/HelpAlert.jsf b/samples/woodstock/example/alert/HelpAlert.jsf new file mode 100644 index 0000000..ffcacb7 --- /dev/null +++ b/samples/woodstock/example/alert/HelpAlert.jsf @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/alert/InlineAlert.jsf b/samples/woodstock/example/alert/InlineAlert.jsf new file mode 100644 index 0000000..b457e36 --- /dev/null +++ b/samples/woodstock/example/alert/InlineAlert.jsf @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/alert/PageAlert.jsf b/samples/woodstock/example/alert/PageAlert.jsf new file mode 100644 index 0000000..7396427 --- /dev/null +++ b/samples/woodstock/example/alert/PageAlert.jsf @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/alert/PageAlertExample.jsf b/samples/woodstock/example/alert/PageAlertExample.jsf new file mode 100644 index 0000000..0b6198a --- /dev/null +++ b/samples/woodstock/example/alert/PageAlertExample.jsf @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/button/Button.jsf b/samples/woodstock/example/button/Button.jsf new file mode 100644 index 0000000..c840e07 --- /dev/null +++ b/samples/woodstock/example/button/Button.jsf @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + +
    + +"

    +
    + + + + + + + + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/button/ButtonResults.jsf b/samples/woodstock/example/button/ButtonResults.jsf new file mode 100644 index 0000000..98b36e3 --- /dev/null +++ b/samples/woodstock/example/button/ButtonResults.jsf @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + +"
    + +"
    + +"
    + +"
    +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/cbrb/checkboxRadiobutton.jsf b/samples/woodstock/example/cbrb/checkboxRadiobutton.jsf new file mode 100644 index 0000000..d643e16 --- /dev/null +++ b/samples/woodstock/example/cbrb/checkboxRadiobutton.jsf @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + +
     
    + + + + +
    + + + +
    +
    + + + +
    +
    + + + +
    +
     
    + + + + +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    + +
    +
    + + + + + + + + + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/cbrb/checkboxRadiobuttonResults.jsf b/samples/woodstock/example/cbrb/checkboxRadiobuttonResults.jsf new file mode 100644 index 0000000..0ecee20 --- /dev/null +++ b/samples/woodstock/example/cbrb/checkboxRadiobuttonResults.jsf @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + +"
    + +"
    + +"
    +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/chooseruploader/fileChooser.jsf b/samples/woodstock/example/chooseruploader/fileChooser.jsf new file mode 100644 index 0000000..757b824 --- /dev/null +++ b/samples/woodstock/example/chooseruploader/fileChooser.jsf @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + +" + + +" + + +"
    + +"
       + + + +"
    + +"
    +
    +
    + + + +
    +
    +
    +
    diff --git a/samples/woodstock/example/chooseruploader/fileChooserPopup.jsf b/samples/woodstock/example/chooseruploader/fileChooserPopup.jsf new file mode 100644 index 0000000..5f068a2 --- /dev/null +++ b/samples/woodstock/example/chooseruploader/fileChooserPopup.jsf @@ -0,0 +1,47 @@ + + + + + + + + + + + +"
    + + + + + + + + + + +
    ]]> + +
    ]]> + +
    ]]> + + + + + + diff --git a/samples/woodstock/example/chooseruploader/fileUploader.jsf b/samples/woodstock/example/chooseruploader/fileUploader.jsf new file mode 100644 index 0000000..3489aff --- /dev/null +++ b/samples/woodstock/example/chooseruploader/fileUploader.jsf @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +   +
    + + + +
    + + + + +"
    +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/chooseruploader/fileUploaderPopup.jsf b/samples/woodstock/example/chooseruploader/fileUploaderPopup.jsf new file mode 100644 index 0000000..3246c3a --- /dev/null +++ b/samples/woodstock/example/chooseruploader/fileUploaderPopup.jsf @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + +
    + + + + + + + + + +
    + + + + +
    + + + + + + +"
    +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/chooseruploader/folderChooser.jsf b/samples/woodstock/example/chooseruploader/folderChooser.jsf new file mode 100644 index 0000000..4367ec2 --- /dev/null +++ b/samples/woodstock/example/chooseruploader/folderChooser.jsf @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + +" + + +" + + +"
    + +"
       + + + +"
    + +"
    +
    +
    + + + +
    +
    +
    +
    diff --git a/samples/woodstock/example/chooseruploader/folderChooserPopup.jsf b/samples/woodstock/example/chooseruploader/folderChooserPopup.jsf new file mode 100644 index 0000000..834f6ee --- /dev/null +++ b/samples/woodstock/example/chooseruploader/folderChooserPopup.jsf @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + +"
    + + + + + + + + + + +" + + +"
    + +"
    + +"
    +
    +
    + + + +
    +
    +
    +
    diff --git a/samples/woodstock/example/chooseruploader/index.jsf b/samples/woodstock/example/chooseruploader/index.jsf new file mode 100644 index 0000000..a9c94b4 --- /dev/null +++ b/samples/woodstock/example/chooseruploader/index.jsf @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    + + +"
    +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/field/TextInput.jsf b/samples/woodstock/example/field/TextInput.jsf new file mode 100644 index 0000000..b7aff91 --- /dev/null +++ b/samples/woodstock/example/field/TextInput.jsf @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + +
     
    + + + + + + + + +
     
    + + +" + + + +
     
    +
    + + + + + + + + + + + + +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/field/TextInputResults.jsf b/samples/woodstock/example/field/TextInputResults.jsf new file mode 100644 index 0000000..1be4ee6 --- /dev/null +++ b/samples/woodstock/example/field/TextInputResults.jsf @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + +"
    + +"
    + +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/images/check_all.gif b/samples/woodstock/example/images/check_all.gif new file mode 100644 index 0000000..9a64803 Binary files /dev/null and b/samples/woodstock/example/images/check_all.gif differ diff --git a/samples/woodstock/example/images/example_primary_masthead.png b/samples/woodstock/example/images/example_primary_masthead.png new file mode 100644 index 0000000..950db94 Binary files /dev/null and b/samples/woodstock/example/images/example_primary_masthead.png differ diff --git a/samples/woodstock/example/images/favicon.ico b/samples/woodstock/example/images/favicon.ico new file mode 100644 index 0000000..3111163 Binary files /dev/null and b/samples/woodstock/example/images/favicon.ico differ diff --git a/samples/woodstock/example/images/pool_tree.gif b/samples/woodstock/example/images/pool_tree.gif new file mode 100644 index 0000000..19ad6f4 Binary files /dev/null and b/samples/woodstock/example/images/pool_tree.gif differ diff --git a/samples/woodstock/example/images/tree_document_critical.gif b/samples/woodstock/example/images/tree_document_critical.gif new file mode 100644 index 0000000..5b8248c Binary files /dev/null and b/samples/woodstock/example/images/tree_document_critical.gif differ diff --git a/samples/woodstock/example/images/tree_document_down.gif b/samples/woodstock/example/images/tree_document_down.gif new file mode 100644 index 0000000..89b7e2c Binary files /dev/null and b/samples/woodstock/example/images/tree_document_down.gif differ diff --git a/samples/woodstock/example/images/tree_document_major.gif b/samples/woodstock/example/images/tree_document_major.gif new file mode 100644 index 0000000..c9318c4 Binary files /dev/null and b/samples/woodstock/example/images/tree_document_major.gif differ diff --git a/samples/woodstock/example/images/tree_document_minor.gif b/samples/woodstock/example/images/tree_document_minor.gif new file mode 100644 index 0000000..32dd4f5 Binary files /dev/null and b/samples/woodstock/example/images/tree_document_minor.gif differ diff --git a/samples/woodstock/example/images/tree_server.gif b/samples/woodstock/example/images/tree_server.gif new file mode 100644 index 0000000..f3d2249 Binary files /dev/null and b/samples/woodstock/example/images/tree_server.gif differ diff --git a/samples/woodstock/example/images/version_product_name.png b/samples/woodstock/example/images/version_product_name.png new file mode 100644 index 0000000..944d9a1 Binary files /dev/null and b/samples/woodstock/example/images/version_product_name.png differ diff --git a/samples/woodstock/example/images/volumegroup_tree.gif b/samples/woodstock/example/images/volumegroup_tree.gif new file mode 100644 index 0000000..351fe88 Binary files /dev/null and b/samples/woodstock/example/images/volumegroup_tree.gif differ diff --git a/samples/woodstock/example/index.jsf b/samples/woodstock/example/index.jsf new file mode 100644 index 0000000..c952097 --- /dev/null +++ b/samples/woodstock/example/index.jsf @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/label/Help.jsf b/samples/woodstock/example/label/Help.jsf new file mode 100644 index 0000000..285eac7 --- /dev/null +++ b/samples/woodstock/example/label/Help.jsf @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/label/Label.jsf b/samples/woodstock/example/label/Label.jsf new file mode 100644 index 0000000..e1bf05f --- /dev/null +++ b/samples/woodstock/example/label/Label.jsf @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + +"
    + +
    + + + + + + + + + + + + + + + +"
    + + + + + + +"

    + +"
    + +"
    + +"
    + + +"

    + +"
    + +"
    + +"
    + + +"


    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + +
     
    + + + + + + + +
    + +

    + +
    + + + + + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/label/LabelResults.jsf b/samples/woodstock/example/label/LabelResults.jsf new file mode 100644 index 0000000..2a594ac --- /dev/null +++ b/samples/woodstock/example/label/LabelResults.jsf @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + +"
    + +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/menu/MenuList.jsf b/samples/woodstock/example/menu/MenuList.jsf new file mode 100644 index 0000000..4965569 --- /dev/null +++ b/samples/woodstock/example/menu/MenuList.jsf @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + +
      + + + +
     
     
    + + + + + + + + + +
      + + + +
     
     
    + + + + + + + + + + + " Comp: #{lb.class.name} + " Comp: #{lb.rendererType} + +
     
      + + + + +
     
    + +
    + + + + + + + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/menu/MenuListResults.jsf b/samples/woodstock/example/menu/MenuListResults.jsf new file mode 100644 index 0000000..41192e3 --- /dev/null +++ b/samples/woodstock/example/menu/MenuListResults.jsf @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"

    + +"

    + + + + + +"

    + + + + +
    + +
    +
    +
    +
    diff --git a/samples/woodstock/example/orderablelist/OrderableList.jsf b/samples/woodstock/example/orderablelist/OrderableList.jsf new file mode 100644 index 0000000..a847835 --- /dev/null +++ b/samples/woodstock/example/orderablelist/OrderableList.jsf @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/orderablelist/OrderableListResults.jsf b/samples/woodstock/example/orderablelist/OrderableListResults.jsf new file mode 100644 index 0000000..d807afa --- /dev/null +++ b/samples/woodstock/example/orderablelist/OrderableListResults.jsf @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + + + + + + + + + + + +
    +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/actions.jsf b/samples/woodstock/example/table/actions.jsf new file mode 100644 index 0000000..32cbf67 --- /dev/null +++ b/samples/woodstock/example/table/actions.jsf @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + +#include "table/actionsTop.jsf" + + + + + + +#include "table/actionsBottom.jsf" + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/actionsBottom.jsf b/samples/woodstock/example/table/actionsBottom.jsf new file mode 100644 index 0000000..da3b818 --- /dev/null +++ b/samples/woodstock/example/table/actionsBottom.jsf @@ -0,0 +1,26 @@ + + + + + + diff --git a/samples/woodstock/example/table/actionsTop.jsf b/samples/woodstock/example/table/actionsTop.jsf new file mode 100644 index 0000000..85c0baa --- /dev/null +++ b/samples/woodstock/example/table/actionsTop.jsf @@ -0,0 +1,26 @@ + + + + + + diff --git a/samples/woodstock/example/table/alarms.jsf b/samples/woodstock/example/table/alarms.jsf new file mode 100644 index 0000000..ccc09b1 --- /dev/null +++ b/samples/woodstock/example/table/alarms.jsf @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/basicTable.jsf b/samples/woodstock/example/table/basicTable.jsf new file mode 100644 index 0000000..a3a469b --- /dev/null +++ b/samples/woodstock/example/table/basicTable.jsf @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/customTitle.jsf b/samples/woodstock/example/table/customTitle.jsf new file mode 100644 index 0000000..1db62f1 --- /dev/null +++ b/samples/woodstock/example/table/customTitle.jsf @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/dynamicGroupTable.jsf b/samples/woodstock/example/table/dynamicGroupTable.jsf new file mode 100644 index 0000000..2d105e1 --- /dev/null +++ b/samples/woodstock/example/table/dynamicGroupTable.jsf @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/dynamicTable.jsf b/samples/woodstock/example/table/dynamicTable.jsf new file mode 100644 index 0000000..b33f338 --- /dev/null +++ b/samples/woodstock/example/table/dynamicTable.jsf @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/embeddedActions.jsf b/samples/woodstock/example/table/embeddedActions.jsf new file mode 100644 index 0000000..f39b0eb --- /dev/null +++ b/samples/woodstock/example/table/embeddedActions.jsf @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/emptyCells.jsf b/samples/woodstock/example/table/emptyCells.jsf new file mode 100644 index 0000000..9b436aa --- /dev/null +++ b/samples/woodstock/example/table/emptyCells.jsf @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + +"
    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/filter.jsf b/samples/woodstock/example/table/filter.jsf new file mode 100644 index 0000000..9642058 --- /dev/null +++ b/samples/woodstock/example/table/filter.jsf @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + + + +#include "table/filterPanel.jsf" + + + + +"

    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/filterPanel.jsf b/samples/woodstock/example/table/filterPanel.jsf new file mode 100644 index 0000000..8a5ed60 --- /dev/null +++ b/samples/woodstock/example/table/filterPanel.jsf @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/samples/woodstock/example/table/groupTable.jsf b/samples/woodstock/example/table/groupTable.jsf new file mode 100644 index 0000000..3ac4412 --- /dev/null +++ b/samples/woodstock/example/table/groupTable.jsf @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + +"
    + +"
    + + +"

    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/hiddenRowsActionsBottom.jsf b/samples/woodstock/example/table/hiddenRowsActionsBottom.jsf new file mode 100644 index 0000000..9925441 --- /dev/null +++ b/samples/woodstock/example/table/hiddenRowsActionsBottom.jsf @@ -0,0 +1,26 @@ + + + + + + diff --git a/samples/woodstock/example/table/hiddenRowsActionsTop.jsf b/samples/woodstock/example/table/hiddenRowsActionsTop.jsf new file mode 100644 index 0000000..2be3480 --- /dev/null +++ b/samples/woodstock/example/table/hiddenRowsActionsTop.jsf @@ -0,0 +1,26 @@ + + + + + + diff --git a/samples/woodstock/example/table/hiddenSelectedRows.jsf b/samples/woodstock/example/table/hiddenSelectedRows.jsf new file mode 100644 index 0000000..ecb2c3d --- /dev/null +++ b/samples/woodstock/example/table/hiddenSelectedRows.jsf @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + +#include "table/hiddenRowsActionsTop.jsf" + + + + + + +#include "table/hiddenRowsActionsBottom.jsf" + + + + +"
    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/index.jsf b/samples/woodstock/example/table/index.jsf new file mode 100644 index 0000000..718a607 --- /dev/null +++ b/samples/woodstock/example/table/index.jsf @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/woodstock/example/table/js/actions.js b/samples/woodstock/example/table/js/actions.js new file mode 100644 index 0000000..e04efc6 --- /dev/null +++ b/samples/woodstock/example/table/js/actions.js @@ -0,0 +1,87 @@ +// diff --git a/samples/woodstock/example/table/js/filter.js b/samples/woodstock/example/table/js/filter.js new file mode 100644 index 0000000..b65464c --- /dev/null +++ b/samples/woodstock/example/table/js/filter.js @@ -0,0 +1,54 @@ +// diff --git a/samples/woodstock/example/table/js/preferences.js b/samples/woodstock/example/table/js/preferences.js new file mode 100644 index 0000000..4bfd2ad --- /dev/null +++ b/samples/woodstock/example/table/js/preferences.js @@ -0,0 +1,34 @@ +// diff --git a/samples/woodstock/example/table/js/select.js b/samples/woodstock/example/table/js/select.js new file mode 100644 index 0000000..b38f20a --- /dev/null +++ b/samples/woodstock/example/table/js/select.js @@ -0,0 +1,43 @@ +// diff --git a/samples/woodstock/example/table/liteTable.jsf b/samples/woodstock/example/table/liteTable.jsf new file mode 100644 index 0000000..606a3a2 --- /dev/null +++ b/samples/woodstock/example/table/liteTable.jsf @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/multipleHeadersFooters.jsf b/samples/woodstock/example/table/multipleHeadersFooters.jsf new file mode 100644 index 0000000..f06e47b --- /dev/null +++ b/samples/woodstock/example/table/multipleHeadersFooters.jsf @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/paginatedTable.jsf b/samples/woodstock/example/table/paginatedTable.jsf new file mode 100644 index 0000000..14cf6bd --- /dev/null +++ b/samples/woodstock/example/table/paginatedTable.jsf @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + +"
    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/preferences.jsf b/samples/woodstock/example/table/preferences.jsf new file mode 100644 index 0000000..72ff578 --- /dev/null +++ b/samples/woodstock/example/table/preferences.jsf @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + +#include "table/preferencesPanel.jsf" + + + + +"
    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/preferencesPanel.jsf b/samples/woodstock/example/table/preferencesPanel.jsf new file mode 100644 index 0000000..e556a63 --- /dev/null +++ b/samples/woodstock/example/table/preferencesPanel.jsf @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/samples/woodstock/example/table/selectMultipleRows.jsf b/samples/woodstock/example/table/selectMultipleRows.jsf new file mode 100644 index 0000000..180044b --- /dev/null +++ b/samples/woodstock/example/table/selectMultipleRows.jsf @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + +"
    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/selectSingleRow.jsf b/samples/woodstock/example/table/selectSingleRow.jsf new file mode 100644 index 0000000..7790be0 --- /dev/null +++ b/samples/woodstock/example/table/selectSingleRow.jsf @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + +"
    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/sortableTable.jsf b/samples/woodstock/example/table/sortableTable.jsf new file mode 100644 index 0000000..b06bafe --- /dev/null +++ b/samples/woodstock/example/table/sortableTable.jsf @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + +"
    + + +"

    + + +"

    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/spacerColumn.jsf b/samples/woodstock/example/table/spacerColumn.jsf new file mode 100644 index 0000000..9ecc5d0 --- /dev/null +++ b/samples/woodstock/example/table/spacerColumn.jsf @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + +"
    + + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/example/table/table.jsf b/samples/woodstock/example/table/table.jsf new file mode 100644 index 0000000..c3f7ef3 --- /dev/null +++ b/samples/woodstock/example/table/table.jsf @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"
    + + + + + + + + + + + + + + + + + + +#include "table/actionsTop.jsf" + + + + + + +#include "table/actionsBottom.jsf" + + + + + + + + + + + +#include "table/filterPanel.jsf" + + + + + + +#include "table/preferencesPanel.jsf" + + + + +"
    + +
    +
    +
    +
    +
    diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/addremove/AddRemoveBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/addremove/AddRemoveBackingBean.java new file mode 100644 index 0000000..c6b5010 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/addremove/AddRemoveBackingBean.java @@ -0,0 +1,310 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.addremove; + +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.component.AddRemove; + +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; +import javax.faces.application.FacesMessage; +import javax.faces.application.FacesMessage.Severity; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.common.UserData; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +import java.io.Serializable; + +/** + * Backing bean for Add Remove example. + */ +public class AddRemoveBackingBean implements Serializable { + + /** Holds value of property availableOptions. */ + private Option[] availableOptions = null; + + /** Holds value of property selectedOptions. */ + private String[] selectedOptions = null; + + /** Holds value of property alertDetail. */ + private String alertDetail = null; + + /** Holds value of property alertRendered. */ + private boolean alertRendered = false; + + /** Holds value of property vertiaclLayout. */ + private boolean verticalLayout = false; + + /** Holds value of property linkText. */ + private String linkText = null; + + /** Holds value of property labelText. */ + private String labelText = null; + + /** Options used in the available listbox for horizontal layout. */ + private Option[] horizontalOptions = null; + + /** Options used in the available listbox for vertical layout. */ + private Option[] verticalOptions = null; + + /** UserData. */ + private UserData userData = null; + + /** Outcome strings used for navigation handling in the faces config file. */ + private static final String SHOW_ADDREMOVE_RESULTS = "showAddRemoveResults"; + private static final String SHOW_ADDREMOVE_EXAMPLE = "showAddRemove"; + + /** Default constructor. */ + public AddRemoveBackingBean() { + // Options used to populate the available listbox for horizontal layout. + horizontalOptions = new Option[10]; + horizontalOptions[0] = new Option("addremove_author1", + MessageUtil.getMessage("addremove_author1")); + horizontalOptions[1] = new Option("addremove_author2", + MessageUtil.getMessage("addremove_author2")); + horizontalOptions[2] = new Option("addremove_author3", + MessageUtil.getMessage("addremove_author3")); + horizontalOptions[3] = new Option("addremove_author4", + MessageUtil.getMessage("addremove_author4")); + horizontalOptions[4] = new Option("addremove_author5", + MessageUtil.getMessage("addremove_author5")); + horizontalOptions[5] = new Option("addremove_author6", + MessageUtil.getMessage("addremove_author6")); + horizontalOptions[6] = new Option("addremove_author7", + MessageUtil.getMessage("addremove_author7")); + horizontalOptions[7] = new Option("addremove_author8", + MessageUtil.getMessage("addremove_author8")); + horizontalOptions[8] = new Option("addremove_author9", + MessageUtil.getMessage("addremove_author9")); + horizontalOptions[9] = new Option("addremove_author10", + MessageUtil.getMessage("addremove_author10")); + + // Options used to populate the available listbox for vertical layout. + verticalOptions = new Option[10]; + verticalOptions[0] = new Option("addremove_book1v", + MessageUtil.getMessage("addremove_book1v")); + verticalOptions[1] = new Option("addremove_book2v", + MessageUtil.getMessage("addremove_book2v")); + verticalOptions[2] = new Option("addremove_book3v", + MessageUtil.getMessage("addremove_book3v")); + verticalOptions[3] = new Option("addremove_book4v", + MessageUtil.getMessage("addremove_book4v")); + verticalOptions[4] = new Option("addremove_book5v", + MessageUtil.getMessage("addremove_book5v")); + verticalOptions[5] = new Option("addremove_book6v", + MessageUtil.getMessage("addremove_book6v")); + verticalOptions[6] = new Option("addremove_book7", + MessageUtil.getMessage("addremove_book7v")); + verticalOptions[7] = new Option("addremove_book8v", + MessageUtil.getMessage("addremove_book8v")); + verticalOptions[8] = new Option("addremove_book9v", + MessageUtil.getMessage("addremove_book9v")); + verticalOptions[9] = new Option("addremove_book10v", + MessageUtil.getMessage("addremove_book10v")); + + // Set the availableOptions property with the + // options for the horizontal layout. + availableOptions = horizontalOptions; + } + + /** Get the value of property availableOptions. */ + public Option[] getAvailableOptions() { + return this.availableOptions; + } + + /** Set the value of property availableOptions. */ + public void setAvailableOptions(Option[] availableOptions) { + this.availableOptions = availableOptions; + } + + /** Get the value of property selectedOptions. */ + public String[] getSelectedOptions() { + return this.selectedOptions; + } + + /** Set the value of property selectedOptions. */ + public void setSelectedOptions(String[] selectedOptions) { + this.selectedOptions = selectedOptions; + } + + /** Return the alert detail message. */ + public String getAlertDetail() { + alertDetail = (verticalLayout) + ? MessageUtil.getMessage("addremove_noBookSelection") + : MessageUtil.getMessage("addremove_noAuthorSelection"); + return alertDetail; + } + + /** Return the render state of the alert. */ + public boolean getAlertRendered() { + // Inline alert should show up when the addremove + // component on the page becomes invalid. + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if(severity == null) { + alertRendered = false; + } else { + if(severity.compareTo(FacesMessage.SEVERITY_ERROR) == 0) { + alertRendered = true; + } + } + return alertRendered; + } + + /** Get the value of property verticalLayout. */ + public boolean getVerticalLayout() { + return verticalLayout; + } + + /** Return the text description of the hyperlink. */ + public String getLinkText() { + linkText = (verticalLayout) + ? MessageUtil.getMessage("addremove_showHorizontal") + : MessageUtil.getMessage("addremove_showVertical"); + + return linkText; + } + + /** Return the text for the addremove's label. */ + public String getLabelText() { + return ((verticalLayout) + ? MessageUtil.getMessage("addremove_selectBooks") + : MessageUtil.getMessage("addremove_selectAuthors")); + } + + /** Get UserData created with an option array containing user selections. */ + public UserData getUserData() { + if (userData == null) { + Option[] selected = new Option[selectedOptions.length]; + for (int i = 0; i < selectedOptions.length; i++) { + for (int j = 0; j < availableOptions.length; j++) { + if (selectedOptions[i].equals(availableOptions[j].getValue())) { + selected[i] = availableOptions[j]; + } + } + } + userData = new UserData(selected); + } + + return userData; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Handlers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action handler for the orientation hyperlink. */ + public String orientationLinkActionHandler() { + // Change the orientation of the add-remove componenet, + // so that the page is re-displayed with the correct layout. + verticalLayout = (verticalLayout) ? false : true; + + // Set the appropriate options in the available listbox + // based on the new layout. + if (verticalLayout) { + availableOptions = verticalOptions; + } else { + availableOptions = horizontalOptions; + } + + // We don't want the addremove model object to get updated with + // its submitted value each time the orientation of the component + // is changed. So, we need to null out the submitted value. + FacesContext context = FacesContext.getCurrentInstance(); + AddRemove addremove = + (AddRemove) context.getViewRoot().findComponent( + "form:contentPageTitle:addRemove"); + addremove.setSubmittedValue(null); + selectedOptions = null; + + // Return null to cause the page to re-render. + return null; + } + + /** Action handler for the "ShowItems" button. */ + public String showItemsButtonActionHandler() { + return SHOW_ADDREMOVE_RESULTS; + } + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + /** Action handler when navigating to the addremove example. */ + public String showAddRemoveExample() { + return SHOW_ADDREMOVE_EXAMPLE; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Listeners + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action listener for the preset button. */ + public void presetList(ActionEvent e) { + // Sine the action is immediate, the add remove component won't + // go through the Update Model phase. However, its submitted value + // gets set in the Apply Request Value phase and this value is retained + // when the page is redisplayed. + // + // So, we need to explicitly erase the submitted value and then update + // the model object with the initial state. + FacesContext context = FacesContext.getCurrentInstance(); + AddRemove addremove = + (AddRemove) context.getViewRoot().findComponent( + "form:contentPageTitle:addRemove"); + addremove.setSubmittedValue(null); + preset(); + } + + /** Action listener for the ShowItems button. */ + public void resetDataProvider(ActionEvent e) { + // reset data provider; + userData = null; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private Methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Helper method to preset the listboxes with initial values. */ + private void preset() { + // Set options 9-10 in selected listbox. + if (verticalLayout) { + this.selectedOptions = new String[] {"addremove_book9v", + "addremove_book10v"}; + } else { + this.selectedOptions = new String[] {"addremove_author9", + "addremove_author10"}; + } + } + + /** Reset. */ + private void reset() { + verticalLayout = false; + selectedOptions = null; + availableOptions = horizontalOptions; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/alert/InlineAlertBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/alert/InlineAlertBackingBean.java new file mode 100644 index 0000000..d181414 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/alert/InlineAlertBackingBean.java @@ -0,0 +1,303 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.alert; + +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.validator.ValidatorException; +import javax.faces.application.FacesMessage; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +import java.util.Random; +import java.io.Serializable; + +/** + * Backing bean for Inline Alert example. + */ +public class InlineAlertBackingBean implements Serializable { + + // Outcome strings used in the faces config. + private final static String SHOW_INLINE_ALERT = "showInlineAlert"; + private final static String SHOW_ALERT_INDEX = "showAlertIndex"; + + // Holds value of property fieldValue. + private Integer fieldValue; + + // Holds value of property disabled. + private boolean disabled = false; + + // Holds value of property alertSummary. + private String alertSummary = null; + + // Holds value of property alertDetail. + private String alertDetail = null; + + // Holds value of property alertType. + private String alertType = null; + + // Holds value of property alertRendered. + private boolean alertRendered = false; + + // Holds value of property linkRendered. + private boolean linkRendered = false; + + // Random number + private int randomNumber = 0; + + // Number of attempts + private int attempts = 0; + + // User guess + private int guess = 0; + + /** Default constructor */ + public InlineAlertBackingBean() { + } + + /** Set the value of property fieldValue. */ + public void setFieldValue(Integer fieldValue) { + this.fieldValue = fieldValue; + } + + /** Get the value of property fieldValue. */ + public Integer getFieldValue() { + return fieldValue; + } + + /** Get the value of property disabled. */ + public boolean getDisabled() { + return disabled; + } + + /** Get the value of property alertSummary. */ + public String getAlertSummary() { + if (isTextInvalid()) { + alertSummary = MessageUtil.getMessage("alert_sumException"); + } + return alertSummary; + } + + /** Get the value of property alertDetail. */ + public String getAlertDetail() { + if (isTextInvalid()) { + alertDetail = null; + } + return alertDetail; + } + + /** Get the value of property alertType. */ + public String getAlertType() { + if (isTextInvalid()) { + alertType = "error"; + } + return alertType; + } + + /** Get the value of property alertRendered. */ + public boolean getAlertRendered() { + if (isTextInvalid()) { + alertRendered = true; + } + return alertRendered; + } + + /** Get the value of property linkRendered. */ + public boolean getLinkRendered() { + if (isTextInvalid()) { + linkRendered = false; + } + return linkRendered; + } + + /** + * Text field validator. This will ONLY be called if a value + * was specified. + */ + public void validateFieldEntry(FacesContext context, UIComponent component, + Object value) throws ValidatorException { + + int num = ((Integer) value).intValue(); + + // Number must be between 1 and 10. + if (num < 1 || num > 10) { + setAlertInfo("error", "alert_sumException", null, null, false); + FacesMessage message = new FacesMessage(); + message.setDetail(MessageUtil.getMessage("alert_sumException")); + message.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(message); + } + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Handlers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action handler for the Enter button. */ + public String handleAction() { + // Return null to cause the page to re-render. + return null; + } + + /** Action handler for the restart button. */ + public String restart() { + resetAll(); + // Return null to cause the page to re-render. + return null; + } + + /** Action handler when navigating to the inline alert example. */ + public String showInlineAlert() { + return SHOW_INLINE_ALERT; + } + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + resetAll(); + return IndexBackingBean.INDEX_ACTION; + } + + /** Action handler when navigating to the alert example index. */ + public String showAlertIndex() { + fieldValue = null; + disabled = false; + alertRendered = false; + return SHOW_ALERT_INDEX; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Listeners + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action listener for the Enter button. */ + public void processButtonAction(ActionEvent ae) { + + // Get the random number + if (randomNumber == 0) { + Random r = new Random(); + randomNumber = r.nextInt(10) + 1; + } + + try { + // Get the value entered. + guess = fieldValue.intValue(); + attempts++; + + // Test guess with random number and display the appropriate + // message. + if (guess == randomNumber) { + setAlertInfo("success", "alert_sumCongrats", + "alert_number", String.valueOf(randomNumber), false); + // Disable the button. + disabled = true; + reset(); + } else if (attempts >= 3) { + setAlertInfo("information", "alert_sumWrong", "alert_number", + String.valueOf(randomNumber), false); + // Disable the button. + disabled = true; + reset(); + } else if (attempts == 2) { + if (guess < randomNumber) { + setAlertInfo("warning", "alert_sumLastChance", + "alert_detHigher", null, true); + } else + setAlertInfo("warning", "alert_sumLastChance", + "alert_detLower", null, true); + } else { + if (guess < randomNumber) { + setAlertInfo("warning", "alert_sumTryAgain", + "alert_detHigher", null, true); + } else + setAlertInfo("warning", "alert_sumTryAgain", + "alert_detLower", null, true); + } + } catch (Exception e) { + setAlertInfo("error", "alert_sumException", null, null, false); + } + + // Reset the field value so that the old guess doesn't + // remain in the field. + fieldValue = null; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private Methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Set the alert properties that will be used by that component. + * + * @param type The alert type. + * @param summary The alert summary message key. + * @param detail The alert detail message key. + * @param detailArg The alert detail message arguments. + * @param rendered The rendered value for the alert link. + */ + private void setAlertInfo(String type, String summary, + String detail, String detailArg, boolean rendered) { + + String[] args = {detailArg}; + if (detailArg != null) { + alertDetail = MessageUtil.getMessage(detail, args); + } else { + alertDetail = MessageUtil.getMessage(detail); + } + + alertSummary = MessageUtil.getMessage(summary); + alertType = type; + linkRendered = rendered; + + // Set the alertRendered to true so that when the page is + // re-rendered, it shows the alert message. + alertRendered = true; + } + + /** Check to see if text field is invalid. */ + private boolean isTextInvalid() { + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if(severity != null && + severity.compareTo(FacesMessage.SEVERITY_ERROR) == 0) { + return true; + } + return false; + } + + /** Reset to initial values. */ + private void reset() { + guess = 0; + attempts = 0; + randomNumber = 0; + } + + /** Reset all to their initial values. */ + private void resetAll() { + disabled = false; + alertRendered = false; + fieldValue = null; + reset(); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/alert/PageAlertBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/alert/PageAlertBackingBean.java new file mode 100644 index 0000000..e20bd47 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/alert/PageAlertBackingBean.java @@ -0,0 +1,237 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.alert; + +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.validator.ValidatorException; +import javax.faces.application.FacesMessage; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +import java.util.Random; +import java.io.Serializable; + +/** + * Backing bean for Page Alert example. + */ +public class PageAlertBackingBean implements Serializable { + + // Outcome strings used in the faces config. + private final static String SHOW_PAGEALERT_EXAMPLE = "showPageAlertExample"; + private final static String SHOW_PAGEALERT = "showPageAlert"; + private final static String SHOW_ALERT_INDEX = "showAlertIndex"; + + // Holds value of property fieldValue. + private Integer fieldValue; + + // Holds value of property alertTitle. + private String alertTitle = null; + + // Holds value of property alertDetail. + private String alertDetail = null; + + // Holds value of property alertType. + private String alertType = null; + + // Random number + private int randomNumber = 0; + + // Number of attempts + private int count = 0; + + // User guess + private int userGuess; + + /** Default constructor */ + public PageAlertBackingBean() { + } + + /** Set the value of property fieldValue. */ + public void setFieldValue(Integer fieldValue) { + this.fieldValue = fieldValue; + } + + /** Get the value of property fieldValue. */ + public Integer getFieldValue() { + return fieldValue; + } + + /** Get the value of property alertTitle. */ + public String getAlertTitle() { + return alertTitle; + } + + /** Get the value of property alertDetail. */ + public String getAlertDetail() { + return alertDetail; + } + + /** Get the value of property alertType. */ + public String getAlertType() { + return alertType; + } + + /** Display the inline alert if there was an error on the page. */ + public boolean getInlineAlertRendered() { + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if(severity != null && + severity.compareTo(FacesMessage.SEVERITY_ERROR) == 0) { + return true; + } + return false; + } + + /** + * Text field validator. This will ONLY be called if a value + * was specified. + */ + public void validateFieldEntry(FacesContext context, UIComponent component, + Object value) throws ValidatorException { + + int num = ((Integer) value).intValue(); + + // Number must be between 1 and 10. + if (num < 1 || num > 10) { + FacesMessage message = new FacesMessage(); + message.setDetail(MessageUtil.getMessage("alert_sumException")); + message.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(message); + } + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Handlers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action handler when navigating to the page alert example. */ + public String showPageAlertExample() { + return SHOW_PAGEALERT_EXAMPLE; + } + + /** Action handler when navigating to page alert. */ + public String showPageAlert() { + return SHOW_PAGEALERT; + } + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + fieldValue = null; + resetValues(); + return IndexBackingBean.INDEX_ACTION; + } + + /** Action handler when navigating to the alert example index. */ + public String showAlertIndex() { + return SHOW_ALERT_INDEX; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Listeners + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action listener for the Enter button. */ + public void processButtonAction(ActionEvent ae) { + + // Get the random number + if (randomNumber == 0) { + Random r = new Random(); + randomNumber = r.nextInt(10) + 1; + } + + try { + // Get the value entered. + userGuess = fieldValue.intValue(); + count++; + + // Test user guess with random number and display + // the appropriate message. + if (userGuess == randomNumber) { + setAlertInfo("information", "alert_congratHeader", + "alert_numberCongrats", String.valueOf(randomNumber)); + resetValues(); + } else if (count >= 3) { + setAlertInfo("information", "alert_gameOverHeader", + "alert_numberWrong", String.valueOf(randomNumber)); + resetValues(); + } else if (count == 2) { + if (userGuess < randomNumber) { + setAlertInfo("warning", "alert_incorrectNumHeader", + "alert_detHigherLastChance", null); + } else + setAlertInfo("warning", "alert_incorrectNumHeader", + "alert_detLowerLastChance", null); + } else { + if (userGuess < randomNumber) { + setAlertInfo("warning", "alert_incorrectNumHeader", + "alert_detHigherTryAgain", null); + } else { + setAlertInfo("warning", "alert_incorrectNumHeader", + "alert_detLowerTryAgain", null); + } + } + } catch (Exception e) { + setAlertInfo("error", "alert_incorrectNumHeader", + "alert_sumExceptionWithHelp", null); + } + + // Reset the field value so that the old guess doesn't + // remain in the field. + fieldValue = null; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private Methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Set the alert type, title and detail message. + * + * @param type The alert type. + * @param summary The key for the alert title. + * @param detail The alert detail message key. + * @param detailArg The alert detail message arguments. + */ + private void setAlertInfo(String type, String title, + String detail, String detailArg) { + + alertType = type; + alertTitle = MessageUtil.getMessage(title); + + String[] args = {detailArg}; + if (detailArg != null) { + alertDetail = MessageUtil.getMessage(detail, args); + } else { + alertDetail = MessageUtil.getMessage(detail); + } + } + + /** Reset to the initial values. */ + private void resetValues() { + randomNumber = 0; + count = 0; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/button/ButtonBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/button/ButtonBackingBean.java new file mode 100644 index 0000000..1b52fd7 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/button/ButtonBackingBean.java @@ -0,0 +1,304 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +/* + * ButtonBackingBean.java + * + * Created on January 2, 2006, 5:18 PM + */ + +package com.sun.webui.jsf.example.button; + +import java.io.Serializable; + +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; + +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.model.OptionTitle; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +/** + * Backing bean for Button example. + * + * Note that we must implement java.io.Serializable or + * javax.faces.component.StateHolder in case client-side + * state saving is used, or if server-side state saving is + * used with a distributed system. + */ +public class ButtonBackingBean implements Serializable{ + + private Option[] testCaseOptions = null; + private String summary = null; + private String detail = null; + private boolean primaryDisabled = false; + private boolean primaryMiniDisabled = false; + private boolean secondaryDisabled = false; + private boolean secondaryMiniDisabled = false; + + /** Creates a new instance of ButtonBackingBean */ + public ButtonBackingBean() { + testCaseOptions = new Option[3]; + testCaseOptions[0] = new OptionTitle( + MessageUtil.getMessage("button_testCase_title")); + testCaseOptions[1] = new Option("button_testCase_disableAll", + MessageUtil.getMessage("button_testCase_disableAll")); + testCaseOptions[2] = new Option("button_testCase_enableAll", + MessageUtil.getMessage("button_testCase_enableAll")); + } + + /** Return the array of test case options */ + public Option[] getTestCaseOptions() { + return testCaseOptions; + } + + /** Action listener for icon button. */ + public void iconActionListener(ActionEvent e) { + setAlertInfo(e, null); + } + + /** Action listener for primary button. */ + public void primaryActionListener(ActionEvent e) { + setAlertInfo(e, "button_primaryButtonText"); + } + + /** Action listener for primary mini button. */ + public void primaryMiniActionListener(ActionEvent e) { + setAlertInfo(e, "button_primaryMiniButtonText"); + } + + /** Action listener for secondary button. */ + public void secondaryActionListener(ActionEvent e) { + setAlertInfo(e, "button_secondaryButtonText"); + } + + /** Action listener for secondary mini button. */ + public void secondaryMiniActionListener(ActionEvent e) { + setAlertInfo(e, "button_secondaryMiniButtonText"); + } + + /** + * Set the alert summary and detail messages based on the component + * associated with the event. The valueKey is the message key + * for the detail message, or null if no detail is required. + */ + private void setAlertInfo(ActionEvent e, String valueKey) { + FacesContext context = FacesContext.getCurrentInstance(); + String clientID = e.getComponent().getClientId(context); + + // We only want the last part of the fully-qualified clientID + int n = clientID.lastIndexOf(':'); + if (n >= 0) { + clientID = clientID.substring(n + 1); + } + + Object[] args = null; + String detailKey = null; + if (valueKey != null) { + args = new Object[2]; + args[1] = MessageUtil.getMessage(valueKey); + detailKey = "button_alertElementDetail"; + } else { + args = new Object[1]; + detailKey = "button_alertElementDetailNoValue"; + } + args[0] = clientID; + summary = MessageUtil.getMessage("button_alertElement"); + detail = MessageUtil.getMessage(detailKey, args); + } + + /** Action handler for all buttons. */ + public String actionHandler() { + // Returning null causes page to re-render. + return null; + } + + /** Action handler for the test case dropdown menu. */ + public String testCaseActionHandler() { + // Disable the alert by having no summary and detail. + summary = null; + detail = null; + + return null; + } + + /** Return the enable/disable state of the primary button. */ + public boolean getPrimaryDisabled() { + return primaryDisabled; + } + + /** Set the enable/disable state of the primary button. */ + public void setPrimaryDisabled(boolean b) { + primaryDisabled = b; + } + + /** Return the enable/disable state of the primary mini button. */ + public boolean getPrimaryMiniDisabled() { + return primaryMiniDisabled; + } + + /** Set the enable/disable state of the primary mini button. */ + public void setPrimaryMiniDisabled(boolean b) { + primaryMiniDisabled = b; + } + + /** Return the enable/disable state of the secondary button. */ + public boolean getSecondaryDisabled() { + return secondaryDisabled; + } + + /** Set the enable/disable state of the secondary button. */ + public void setSecondaryDisabled(boolean b) { + secondaryDisabled = b; + } + + /** Return the enable/disable state of the secondary mini button. */ + public boolean getSecondaryMiniDisabled() { + return secondaryMiniDisabled; + } + + /** Set the enable/disable state of the secondary mini button. */ + public void setSecondaryMiniDisabled(boolean b) { + secondaryMiniDisabled = b; + } + + /** Return the alert summary message. */ + public String getAlertSummary() { + return summary; + } + + /** Return the alert detail message. */ + public String getAlertDetail() { + return detail; + } + + /** Return the render state of the alert. */ + public boolean getAlertRendered() { + if (summary == null) + return false; + + return true; + } + + /** Return the selected state of the primary button's checkbox. */ + public boolean getPrimaryCBSelected() { + // Checkbox state is inverse of button's disabled state. + return !getPrimaryDisabled(); + } + + /** Set the selected state of the primary button's checkbox. */ + public void setPrimaryCBSelected(boolean b) { + // Checkbox state is inverse of button's disabled state. + setPrimaryDisabled(!b); + } + + /** Return the selected state of the primary mini button's checkbox. */ + public boolean getPrimaryMiniCBSelected() { + // Checkbox state is inverse of button's disabled state. + return !getPrimaryMiniDisabled(); + } + + /** Set the selected state of the primary mini button's checkbox. */ + public void setPrimaryMiniCBSelected(boolean b) { + // Checkbox state is inverse of button's disabled state. + setPrimaryMiniDisabled(!b); + } + + /** Return the selected state of the secondary button's checkbox. */ + public boolean getSecondaryCBSelected() { + // Checkbox state is inverse of button's disabled state. + return !getSecondaryDisabled(); + } + + /** Set the selected state of the secondary button's checkbox. */ + public void setSecondaryCBSelected(boolean b) { + // Checkbox state is inverse of button's disabled state. + setSecondaryDisabled(!b); + } + + /** Return the selected state of the secondary mini button's checkbox. */ + public boolean getSecondaryMiniCBSelected() { + // Checkbox state is inverse of button's disabled state. + return !getSecondaryMiniDisabled(); + } + + /** Set the selected state of the secondary mini button's checkbox. */ + public void setSecondaryMiniCBSelected(boolean b) { + // Checkbox state is inverse of button's disabled state. + setSecondaryMiniDisabled(!b); + } + + // Action handler when navigating to the main example index. + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + private void reset() { + summary = null; + detail = null; + primaryDisabled = false; + primaryMiniDisabled = false; + secondaryDisabled = false; + secondaryMiniDisabled = false; + } + + /** Return the state result for the primary button */ + public String getPrimaryResult() { + String buttonLabel = MessageUtil.getMessage("button_primaryButtonText"); + if (getPrimaryDisabled()) { + return MessageUtil.getMessage("button_resultDisabled", buttonLabel); + } else { + return MessageUtil.getMessage("button_resultEnabled", buttonLabel); + } + } + + /** Return the state result for the primary-mini button */ + public String getPrimaryMiniResult() { + String buttonLabel = MessageUtil.getMessage("button_primaryMiniButtonText"); + if (getPrimaryMiniDisabled()) { + return MessageUtil.getMessage("button_resultDisabled", buttonLabel); + } else { + return MessageUtil.getMessage("button_resultEnabled", buttonLabel); + } + } + + /** Return the state result for the secondary button */ + public String getSecondaryResult() { + String buttonLabel = MessageUtil.getMessage("button_secondaryButtonText"); + if (getSecondaryDisabled()) { + return MessageUtil.getMessage("button_resultDisabled", buttonLabel); + } else { + return MessageUtil.getMessage("button_resultEnabled", buttonLabel); + } + } + + /** Return the state result for the secondary-mini button */ + public String getSecondaryMiniResult() { + String buttonLabel = MessageUtil.getMessage("button_secondaryMiniButtonText"); + if (getSecondaryMiniDisabled()) { + return MessageUtil.getMessage("button_resultDisabled", buttonLabel); + } else { + return MessageUtil.getMessage("button_resultEnabled", buttonLabel); + } + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/cbrb/CheckboxRadiobuttonBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/cbrb/CheckboxRadiobuttonBackingBean.java new file mode 100644 index 0000000..9578b07 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/cbrb/CheckboxRadiobuttonBackingBean.java @@ -0,0 +1,452 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +/* + * CheckboxRadiobuttonBackingBean.java + * + * Created on January 30, 2006, 3:47 PM + */ + +package com.sun.webui.jsf.example.cbrb; + +import java.io.Serializable; + +import javax.faces.event.ValueChangeEvent; +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; + +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.model.OptionTitle; +import com.sun.webui.jsf.component.DropDown; +import com.sun.webui.jsf.component.Checkbox; +import com.sun.webui.jsf.component.RadioButton; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +/** + * + */ +public class CheckboxRadiobuttonBackingBean implements Serializable { + + // Default selection value for the "red" checkbox. + private static final boolean RED_DEFAULT_SELECTED = false; + + // Default selection values for the radio button. + // At most, only one of these should be set to true; + private static final boolean SERVER_DEFAULT_SELECTED = false; + private static final boolean VOLUME_DEFAULT_SELECTED = true; + private static final boolean POOL_DEFAULT_SELECTED = false; + + // Default selection values for the radio button image. + // At most, only one of these should be set to true; + private static final boolean SERVER_IMAGE_DEFAULT_SELECTED = false; + private static final boolean VOLUME_IMAGE_DEFAULT_SELECTED = true; + private static final boolean POOL_IMAGE_DEFAULT_SELECTED = false; + + // Initial selection values are the defaults. + private boolean redSelected = RED_DEFAULT_SELECTED; + private boolean serverSelected = SERVER_DEFAULT_SELECTED; + private boolean volumeSelected = VOLUME_DEFAULT_SELECTED; + private boolean poolSelected = POOL_DEFAULT_SELECTED; + private boolean serverImageSelected = SERVER_IMAGE_DEFAULT_SELECTED; + private boolean volumeImageSelected = VOLUME_IMAGE_DEFAULT_SELECTED; + private boolean poolImageSelected = POOL_IMAGE_DEFAULT_SELECTED; + + private boolean redCBDisabled = false; + private boolean serverRBDisabled = false; + private boolean volumeRBDisabled = false; + private boolean poolRBDisabled = false; + private boolean serverImageRBDisabled = false; + private boolean volumeImageRBDisabled = false; + private boolean poolImageRBDisabled = false; + private Option[] testCaseOptions = null; + + /** Creates a new instance of CheckboxRadiobuttonBackingBean */ + public CheckboxRadiobuttonBackingBean() { + testCaseOptions = new Option[6]; + testCaseOptions[0] = new OptionTitle( + MessageUtil.getMessage("cbrb_testCase_title")); + testCaseOptions[1] = new Option("cbrb_testCase_toggleCheckboxState", + MessageUtil.getMessage("cbrb_testCase_toggleCheckboxState")); + testCaseOptions[2] = new Option("cbrb_testCase_toggleRadiobuttonState", + MessageUtil.getMessage("cbrb_testCase_toggleRadiobuttonState")); + testCaseOptions[3] = new Option("cbrb_testCase_toggleRadiobuttonImageState", + MessageUtil.getMessage("cbrb_testCase_toggleRadiobuttonImageState")); + testCaseOptions[4] = new Option("cbrb_testCase_disableAll", + MessageUtil.getMessage("cbrb_testCase_disableAll")); + testCaseOptions[5] = new Option("cbrb_testCase_enableAll", + MessageUtil.getMessage("cbrb_testCase_enableAll")); + } + + /** Return the array of test case options */ + public Option[] getTestCaseOptions() { + return testCaseOptions; + } + + /** ActionListener for the test case menu */ + public void testCaseActionListener(ActionEvent e) { + DropDown dropDown = (DropDown) e.getComponent(); + String selected = (String) dropDown.getSelected(); + + // Since the action is immediate, the components won't + // go through the Update Model phase. So, we need to explicitly set the + // values and update the model object for the given action selected. + Checkbox cb; + RadioButton rb; + FacesContext context = FacesContext.getCurrentInstance(); + + if (selected.equals("cbrb_testCase_toggleCheckboxState")) { + cb = (Checkbox) context.getViewRoot().findComponent("form1:RedCheckbox"); + cb.setDisabled(!getRedCBDisabled()); + setRedCBDisabled(!getRedCBDisabled()); + + } else if (selected.equals("cbrb_testCase_toggleRadiobuttonState")) { + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbServer"); + rb.setDisabled(!getServerRBDisabled()); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbVolume"); + rb.setDisabled(!getVolumeRBDisabled()); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbPool"); + rb.setDisabled(!getPoolRBDisabled()); + + setServerRBDisabled(!getServerRBDisabled()); + setVolumeRBDisabled(!getVolumeRBDisabled()); + setPoolRBDisabled(!getPoolRBDisabled()); + + } else if (selected.equals("cbrb_testCase_toggleRadiobuttonImageState")) { + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimServer"); + rb.setDisabled(!getServerImageRBDisabled()); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimVolume"); + rb.setDisabled(!getVolumeImageRBDisabled()); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimPool"); + rb.setDisabled(!getPoolImageRBDisabled()); + + setServerImageRBDisabled(!getServerImageRBDisabled()); + setVolumeImageRBDisabled(!getVolumeImageRBDisabled()); + setPoolImageRBDisabled(!getPoolImageRBDisabled()); + + } else if (selected.equals("cbrb_testCase_disableAll")) { + cb = (Checkbox) context.getViewRoot().findComponent("form1:RedCheckbox"); + cb.setDisabled(true); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbServer"); + rb.setDisabled(true); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbVolume"); + rb.setDisabled(true); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbPool"); + rb.setDisabled(true); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimServer"); + rb.setDisabled(true); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimVolume"); + rb.setDisabled(true); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimPool"); + rb.setDisabled(true); + + setRedCBDisabled(true); + setServerRBDisabled(true); + setVolumeRBDisabled(true); + setPoolRBDisabled(true); + setServerImageRBDisabled(true); + setVolumeImageRBDisabled(true); + setPoolImageRBDisabled(true); + + } else if (selected.equals("cbrb_testCase_enableAll")) { + cb = (Checkbox) context.getViewRoot().findComponent("form1:RedCheckbox"); + cb.setDisabled(false); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbServer"); + rb.setDisabled(false); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbVolume"); + rb.setDisabled(false); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbPool"); + rb.setDisabled(false); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimServer"); + rb.setDisabled(false); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimVolume"); + rb.setDisabled(false); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimPool"); + rb.setDisabled(false); + + setRedCBDisabled(false); + setServerRBDisabled(false); + setVolumeRBDisabled(false); + setPoolRBDisabled(false); + setServerImageRBDisabled(false); + setVolumeImageRBDisabled(false); + setPoolImageRBDisabled(false); + } + } + + private void reset() { + // Set the initial selected values + setRedSelected(RED_DEFAULT_SELECTED); + setServerSelected(SERVER_DEFAULT_SELECTED); + setVolumeSelected(VOLUME_DEFAULT_SELECTED); + setPoolSelected(POOL_DEFAULT_SELECTED); + setServerImageSelected(SERVER_IMAGE_DEFAULT_SELECTED); + setVolumeImageSelected(VOLUME_IMAGE_DEFAULT_SELECTED); + setPoolImageSelected(POOL_IMAGE_DEFAULT_SELECTED); + + // Set the initial states + setRedCBDisabled(false); + setServerRBDisabled(false); + setVolumeRBDisabled(false); + setPoolRBDisabled(false); + setServerImageRBDisabled(false); + setVolumeImageRBDisabled(false); + setPoolImageRBDisabled(false); + } + + /** ActionListener for the Reset button */ + public void resetActionListener(ActionEvent e) { + // Since the action is immediate, the components won't + // go through the Update Model phase. However, its submitted value + // gets set in the Apply Request Value phase and this value is retained + // when the page is redisplayed. + // + // So, we need to explicitly erase the submitted values and then update + // the model object with initial values. + Checkbox cb; + RadioButton rb; + + FacesContext context = FacesContext.getCurrentInstance(); + cb = (Checkbox) context.getViewRoot().findComponent("form1:RedCheckbox"); + cb.setSubmittedValue(null); + + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbServer"); + rb.setSubmittedValue(null); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbVolume"); + rb.setSubmittedValue(null); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbPool"); + rb.setSubmittedValue(null); + + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimServer"); + rb.setSubmittedValue(null); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimVolume"); + rb.setSubmittedValue(null); + rb = (RadioButton) context.getViewRoot().findComponent("form1:rbimPool"); + rb.setSubmittedValue(null); + + reset(); + + } + + /** Action handler for the test case dropdown menu. */ + public String testCaseActionHandler() { + // Returning null causes page to re-render. + return null; + } + + /** Return the enable/disable state of the checkbox. */ + public boolean getRedCBDisabled() { + return redCBDisabled; + } + + /** Set the enable/disable state of the checkbox. */ + public void setRedCBDisabled(boolean b) { + redCBDisabled = b; + } + + /** Return the enable/disable state of the server radiobutton. */ + public boolean getServerRBDisabled() { + return serverRBDisabled; + } + + /** Set the enable/disable state of the server radiobutton. */ + public void setServerRBDisabled(boolean b) { + serverRBDisabled = b; + } + + /** Return the enable/disable state of the volume radiobutton. */ + public boolean getVolumeRBDisabled() { + return volumeRBDisabled; + } + + /** Set the enable/disable state of the volume radiobutton. */ + public void setVolumeRBDisabled(boolean b) { + volumeRBDisabled = b; + } + + /** Return the enable/disable state of the pool radiobutton. */ + public boolean getPoolRBDisabled() { + return poolRBDisabled; + } + + /** Set the enable/disable state of the pool radiobutton. */ + public void setPoolRBDisabled(boolean b) { + poolRBDisabled = b; + } + + /** Return the enable/disable state of the server image radiobutton. */ + public boolean getServerImageRBDisabled() { + return serverImageRBDisabled; + } + + /** Set the enable/disable state of the server image radiobutton. */ + public void setServerImageRBDisabled(boolean b) { + serverImageRBDisabled = b; + } + + /** Return the enable/disable state of the volume image radiobutton. */ + public boolean getVolumeImageRBDisabled() { + return volumeImageRBDisabled; + } + + /** Set the enable/disable state of the volume image radiobutton. */ + public void setVolumeImageRBDisabled(boolean b) { + volumeImageRBDisabled = b; + } + + /** Return the enable/disable state of the pool image radiobutton. */ + public boolean getPoolImageRBDisabled() { + return poolImageRBDisabled; + } + + /** Set the enable/disable state of the pool radiobutton. */ + public void setPoolImageRBDisabled(boolean b) { + poolImageRBDisabled = b; + } + + /** Return the selected state of the "red" checkbox */ + public boolean getRedSelected() { + return redSelected; + } + + /** Set the selected state of the "red" checkbox */ + public void setRedSelected(boolean b) { + redSelected = b; + } + + /** Return the selected state of the server radiobutton */ + public boolean getServerSelected() { + return serverSelected; + } + + /** Set the selected state of the server radiobutton */ + public void setServerSelected(boolean b) { + serverSelected = b; + } + + /** Return the selected state of the volume radiobutton */ + public boolean getVolumeSelected() { + return volumeSelected; + } + + /** Set the selected state of the volume radiobutton */ + public void setVolumeSelected(boolean b) { + volumeSelected = b; + } + + /** Return the selected state of the pool radiobutton */ + public boolean getPoolSelected() { + return poolSelected; + } + + /** Set the selected state of the volume radiobutton */ + public void setPoolSelected(boolean b) { + poolSelected = b; + } + + /** Return the selected state of the server image radiobutton */ + public boolean getServerImageSelected() { + return serverImageSelected; + } + + /** Set the selected state of the server image radiobutton */ + public void setServerImageSelected(boolean b) { + serverImageSelected = b; + } + + /** Return the selected state of the volume image radiobutton */ + public boolean getVolumeImageSelected() { + return volumeImageSelected; + } + + /** Set the selected state of the volume image radiobutton */ + public void setVolumeImageSelected(boolean b) { + volumeImageSelected = b; + } + + /** Return the selected state of the pool image radiobutton */ + public boolean getPoolImageSelected() { + return poolImageSelected; + } + + /** Set the selected state of the volume image radiobutton */ + public void setPoolImageSelected(boolean b) { + poolImageSelected = b; + } + + // Action handler when navigating to the main example index. + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + /** Return the state result for the checkbox */ + public String getCheckboxResult() { + String args[] = new String[4]; + args[0] = MessageUtil.getMessage("cbrb_checkboxResult"); + args[1] = MessageUtil.getMessage("crcb_redCheckbox"); + args[2] = getRedSelected() ? MessageUtil.getMessage("cbrb_selected") : MessageUtil.getMessage("cbrb_notSelected"); + args[3] = getRedCBDisabled() ? MessageUtil.getMessage("cbrb_disabled") : MessageUtil.getMessage("cbrb_enabled"); + return MessageUtil.getMessage("cbrb_result", args); + } + + /** Return the state result for the radioButton */ + public String getRadioButtonResult() { + String args[] = new String[4]; + args[0] = MessageUtil.getMessage("cbrb_radioButtonResult"); + if (getServerSelected()) { + args[1] = MessageUtil.getMessage("cbrb_radioButton1"); + args[3] = getServerRBDisabled() ? MessageUtil.getMessage("cbrb_disabled") : MessageUtil.getMessage("cbrb_enabled"); + } + if (getVolumeSelected()) { + args[1] = MessageUtil.getMessage("cbrb_radioButton2"); + args[3] = getVolumeRBDisabled() ? MessageUtil.getMessage("cbrb_disabled") : MessageUtil.getMessage("cbrb_enabled"); + } + if (getPoolSelected()) { + args[1] = MessageUtil.getMessage("cbrb_radioButton3"); + args[3] = getPoolRBDisabled() ? MessageUtil.getMessage("cbrb_disabled") : MessageUtil.getMessage("cbrb_enabled"); + } + args[2] = MessageUtil.getMessage("cbrb_selected"); + + return MessageUtil.getMessage("cbrb_result", args); + } + + /** Return the state result for the radioButton image */ + public String getRadioButtonImageResult() { + String args[] = new String[4]; + args[0] = MessageUtil.getMessage("cbrb_radioButtonImageResult"); + if (getServerImageSelected()) { + args[1] = MessageUtil.getMessage("cbrb_radioButton1"); + args[3] = getServerImageRBDisabled() ? MessageUtil.getMessage("cbrb_disabled") : MessageUtil.getMessage("cbrb_enabled"); + } + if (getVolumeImageSelected()) { + args[1] = MessageUtil.getMessage("cbrb_radioButton2"); + args[3] = getVolumeImageRBDisabled() ? MessageUtil.getMessage("cbrb_disabled") : MessageUtil.getMessage("cbrb_enabled"); + } + if (getPoolImageSelected()) { + args[1] = MessageUtil.getMessage("cbrb_radioButton3"); + args[3] = getPoolImageRBDisabled() ? MessageUtil.getMessage("cbrb_disabled") : MessageUtil.getMessage("cbrb_enabled"); + } + args[2] = MessageUtil.getMessage("cbrb_selected"); + + return MessageUtil.getMessage("cbrb_result", args); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/ChooserUploaderBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/ChooserUploaderBackingBean.java new file mode 100644 index 0000000..160c44f --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/ChooserUploaderBackingBean.java @@ -0,0 +1,259 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.chooseruploader; + +import com.sun.webui.jsf.model.UploadedFile; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.application.FacesMessage; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Backing Bean for Chooser Uploader example. + */ +public class ChooserUploaderBackingBean implements Serializable { + + // String constant. + public static final String WINDOWS_OS = "WINDOW"; + + // Holds value of property lookin. + private File lookin = null; + + // Holds value of property fileChooserLookin. + private File fileChooserLookin = null; + + // Holds value of property selected. + private File selected = null; + + // Holds value of property uploadPath. + private String uploadPath = null; + + // Holds value of property forwardName. + private String forwardName = null; + + // Holds value of property uploadedFile. + private UploadedFile uploadedFile; + + /** Creates a new instance of ChooserUploaderBackingBean */ + public ChooserUploaderBackingBean() { + String osName = System.getProperty("os.name").toUpperCase(); + + if (osName.startsWith(WINDOWS_OS)) { + lookin = new File("c:\\\\windows"); + } else { + lookin = new File("/usr"); + } + fileChooserLookin = new File(lookin.toString()); + } + + /** + * Getter for property uploadedFile. + * @return Value of property uploadedFile. + */ + public UploadedFile getUploadedFile() { + + return this.uploadedFile; + } + + /** + * Setter for property uploadedFile. + * @param uploadedFile New value of property uploadedFile. + */ + public void setUploadedFile(UploadedFile uploadedFile) { + + this.uploadedFile = uploadedFile; + } + + /** + *Getter for property lookin + *@return Value of property lookin. + */ + public File getLookin() { + return lookin; + } + + /** + * Getter for property fileChooserLookin. + */ + public File getFileChooserLookin() { + if (uploadPath != null) { + return (new File(uploadPath)); + } else { + return fileChooserLookin; + } + } + + /** + *Getter method for selected. + */ + public File getSelected() { + return selected; + } + + /** + *Setter method for selected. + */ + public void setSelected(File selected) { + this.selected = selected; + } + + /** + *It creates a temp file and uploads it in a specified directory. + */ + public void writeFile() throws Exception { + + if (uploadedFile == null) { + return; + } + String name = uploadedFile.getOriginalName(); + if (name == null || name.length() == 0) { + name = "tmp.tmp"; + } + + int index = name.indexOf("."); + String suffix = ".tmp"; + if (index != -1) { + suffix = name.substring(name.indexOf(".")); + if (suffix.length() == 0) { + suffix = ".tmp"; + } + } + String prefix = name; + if (index != -1) { + prefix = name.substring(0, name.indexOf(".")); + if (prefix.length() < 3) { + prefix = "tmp"; + } + if (prefix.indexOf("\\") != -1) { + prefix = prefix.replace('\\', '_'); + } + if (prefix.indexOf(":") != -1) { + prefix = prefix.replace(':', '_'); + } + } + File tempDir = null; + if (uploadPath != null) { + tempDir = new File(uploadPath); + } + File tmpFile = File.createTempFile(prefix, suffix, tempDir); + uploadedFile.write(tmpFile); + + } + + /** + *Getter method for uploadPath. + */ + public String getUploadPath() { + return uploadPath; + } + + /** + *Setter method for uploadPath. + */ + public void setUploadPath(String path) { + uploadPath = path; + } + + /** + *Action Listener method. + */ + public void goToPage(ActionEvent e) { + + FacesContext context = FacesContext.getCurrentInstance(); + String ClientId = e.getComponent().getClientId(context); + + if (ClientId.equals("indexForm:fileChooser")) { + forwardName = "fileChooser"; + + } else if (ClientId.equals("indexForm:folderChooser")) { + forwardName = "folderChooser"; + + } else if (ClientId.equals("indexForm:fileUploader")) { + forwardName = "fileUploader"; + + } else { + forwardName = "fileChooserUploader"; + } + } + + /** + * Action method. + */ + public String forwardAction() { + return forwardName; + } + + /** + * Summary message for Validator exception. + */ + public String getSummaryMsg() { + return MessageUtil.getMessage("chooseruploader_summary"); + } + + /** + * Checks for errors on page. + */ + public boolean isErrorsOnPage() { + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) >= 0) { + return true; + } + return false; + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + + lookin = null; + selected = null; + uploadPath = null; + uploadedFile = null; + return IndexBackingBean.INDEX_ACTION; + } + + /** + * Action handler when navigating to the chooser uploader example index. + */ + public String showUploaderIndex() { + + lookin = null; + selected = null; + uploadPath = null; + uploadedFile = null; + return "showChooserUploader"; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/ChooserUploaderValidator.java b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/ChooserUploaderValidator.java new file mode 100644 index 0000000..fc86e00 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/ChooserUploaderValidator.java @@ -0,0 +1,77 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.chooseruploader; + +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; + +import com.sun.webui.jsf.example.common.MessageUtil; + +import java.io.File; + +/** + * Validator class for Chooser/Uploader example. + */ +public class ChooserUploaderValidator implements Validator { + + /** Creates a new instance of ChooserUploaderValidator */ + public ChooserUploaderValidator() { + } + + /** + * This method throws validator exception if specified directory is + * invalid or do not have write permission. + */ + public void validate(FacesContext context, + UIComponent component, Object value) + throws ValidatorException { + + String msgString = null; + FacesMessage msg = null; + + if (value != null) { + String dirPath = (String) value; + File tempDir = new File(dirPath); + + if (!tempDir.isDirectory()) { + msgString = MessageUtil. + getMessage("chooserUploader_invalidDir"); + + msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + + } else if (!tempDir.canWrite()) { + msgString = MessageUtil. + getMessage("chooserUploader_permissionDenied"); + + msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + } + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FileChooserBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FileChooserBackingBean.java new file mode 100644 index 0000000..5ee0cb5 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FileChooserBackingBean.java @@ -0,0 +1,181 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.chooseruploader; + +import javax.faces.context.FacesContext; +import javax.faces.application.FacesMessage; + +import com.sun.webui.jsf.example.index.IndexBackingBean; +import com.sun.webui.jsf.example.common.MessageUtil; + +import java.io.*; +import java.util.List; + + +/** + * Backing Bean for File Chooser example. + */ +public class FileChooserBackingBean implements Serializable { + + // String constant. + public static final String WINDOWS_OS = "WINDOW"; + + // Holds value of property lookin. + private File lookin = null; + + // Holds value of property selected. + private File[] selected; + + /** Creates a new instance of FileChooserBackingBean */ + public FileChooserBackingBean() { + String osName = System.getProperty("os.name").toUpperCase(); + if (osName.startsWith(WINDOWS_OS)) { + lookin = new File("c:\\\\windows"); + } else { + lookin = new File("/usr"); + } + } + + /** + *Getter for property lookin + *@return Value of property lookin. + */ + public File getLookin() { + return lookin; + } + + /** + *returns absolute path for selected objects. + */ + private String valueString(Object object) { + + if (object instanceof List) { + List files = (List)object; + + Object obj = files.get(0); + if (obj instanceof File) { + object = files.toArray(new File[files.size()]); + } else + if (obj instanceof String) { + object = files.toArray(new String[files.size()]); + } else { + String value = files.get(0).toString(); + for (int i = 1; i < files.size(); ++i) { + value = value + ", " + files.get(i).toString(); + } + return value; + } + } + + String value = null; + if (object instanceof File[]) { + File[] files = (File[])object; + value = files[0].getAbsolutePath(); + for (int i = 1; i < files.length; ++i) { + value = value + ", " + files[i].getAbsolutePath(); + } + } else + if (object instanceof File) { + File file = (File)object; + value = file.getAbsolutePath(); + } else + if (object instanceof String[]) { + String[] files = (String[])object; + value = files[0]; + for (int i = 1; i < files.length; ++i) { + value = value + ", " + files[i]; + } + } else + if (object instanceof String) { + String file = (String)object; + value = file; + } + return value; + } + + /** + *Getter method for selected. + */ + public File[] getSelected() { + return selected; + } + + /** + *Setter method for selected. + */ + public void setSelected(File[] selected) { + this.selected = selected; + } + + /** + *Getter method for fileName(s). + */ + public String getFileName() { + + if (selected != null) { + return valueString(selected); + } else return null; + } + + /** + * Summary message for Validator exception. + */ + public String getSummaryMsg() { + return MessageUtil.getMessage("chooseruploader_summary"); + } + + /** + * Checks for errors on page. + */ + public boolean isErrorsOnPage() { + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) >= 0) { + return true; + } + return false; + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + + selected = null; + return IndexBackingBean.INDEX_ACTION; + } + + /** + * Action handler when navigating to the chooser uploader example index. + */ + public String showUploaderIndex() { + + selected = null; + return "showChooserUploader"; + } +} + diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FileUploaderBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FileUploaderBackingBean.java new file mode 100644 index 0000000..0c4d162 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FileUploaderBackingBean.java @@ -0,0 +1,199 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.chooseruploader; + +import com.sun.webui.jsf.model.UploadedFile; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.application.FacesMessage; +import javax.faces.component.UIComponent; +import javax.faces.validator.ValidatorException; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +import java.io.*; +import java.util.List; + + +/** + * Backing Bean for File Uploader example. + */ +public class FileUploaderBackingBean implements Serializable { + + // Holds file name. + private String tmpFileName = null; + + // Holds value of uploadPath property. + private String uploadPath = null; + + // Holds value of property uploadedFile. + private UploadedFile uploadedFile; + + /** Creates a new instance of ChooserUploaderBackingBean */ + public FileUploaderBackingBean() { + } + + /** + * Getter for property uploadedFile. + * @return Value of property uploadedFile. + */ + public UploadedFile getUploadedFile() { + + return this.uploadedFile; + } + + /** + * Setter for property uploadedFile. + * @param uploadedFile New value of property uploadedFile. + */ + public void setUploadedFile(UploadedFile uploadedFile) { + + this.uploadedFile = uploadedFile; + } + + /** + *It creates a temp file and uploads it in default temp directory. + */ + public void writeFile() throws Exception { + + if (uploadedFile == null) { + return; + } + String name = uploadedFile.getOriginalName(); + if (name == null || name.length() == 0) { + name = "tmp.tmp"; + } + + int index = name.indexOf("."); + String suffix = ".tmp"; + if (index != -1) { + suffix = name.substring(name.indexOf(".")); + if (suffix.length() == 0) { + suffix = ".tmp"; + } + } + String prefix = name; + if (index != -1) { + prefix = name.substring(0, name.indexOf(".")); + if (prefix.length() < 3) { + prefix = "tmp"; + } + if (prefix.indexOf("\\") != -1) { + prefix = prefix.replace('\\', '_'); + } + if (prefix.indexOf(":") != -1) { + prefix = prefix.replace(':', '_'); + } + } + + File tmpFile = File.createTempFile(prefix, suffix); + uploadedFile.write(tmpFile); + tmpFileName = tmpFile.getAbsolutePath(); + + } + + /** + *Getter method for fileName. + */ + public String getFileName() { + return tmpFileName; + } + + /** + *Setter method for fileName. + */ + public void setFileName(String fileName) { + tmpFileName = fileName; + } + + /** + * Summary message for Validator exception. + */ + public String getSummaryMsg() { + return MessageUtil.getMessage("chooseruploader_summary"); + } + + /** + * This method throws validator exception if specified file has zero size. + * You can also upload empty files.This method shows the use of validator. + */ + public void validateFile(FacesContext context, + UIComponent component, Object value) + throws ValidatorException { + + String msgString = null; + FacesMessage msg = null; + + if (value != null) { + UploadedFile uploadedFileName = (UploadedFile) value; + long fileSize = uploadedFileName.getSize(); + + if (fileSize == 0) { + msgString = MessageUtil. + getMessage("chooserUploader_invalidFile"); + + msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + } + } + + /** + * Checks for errors on page. + */ + public boolean isErrorsOnPage() { + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) >= 0) { + return true; + } + return false; + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + tmpFileName = null; + uploadPath = null; + uploadedFile = null; + return IndexBackingBean.INDEX_ACTION; + } + + /** + * Action handler when navigating to the chooser uploader example index. + */ + public String showUploaderIndex() { + tmpFileName = null; + uploadPath = null; + uploadedFile = null; + return "showChooserUploader"; + } +} + diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FolderChooserBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FolderChooserBackingBean.java new file mode 100644 index 0000000..8e3c269 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/chooseruploader/FolderChooserBackingBean.java @@ -0,0 +1,182 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.chooseruploader; + +import javax.faces.context.FacesContext; +import javax.faces.application.FacesMessage; + +import com.sun.webui.jsf.model.UploadedFile; +import com.sun.webui.jsf.example.index.IndexBackingBean; +import com.sun.webui.jsf.example.common.MessageUtil; + +import java.io.*; +import java.util.List; + + +/** + * Backing Bean for Folder Chooser example. + */ +public class FolderChooserBackingBean implements Serializable { + + // String constant. + public static final String WINDOWS_OS = "WINDOW"; + + // Holds value of lookin property. + private File lookin = null; + + // Holds value of selected property. + private File selected = null; + + /** Creates a new instance of FileChooserBackingBean */ + public FolderChooserBackingBean() { + String osName = System.getProperty("os.name").toUpperCase(); + if (osName.startsWith(WINDOWS_OS)) { + lookin = new File("c:\\\\windows"); + } else { + lookin = new File("/usr"); + } + } + + /** + *Getter for property lookin + *@return Value of property lookin. + */ + public File getLookin() { + return lookin; + } + + /** + *returns absolute path for selected objects. + */ + private String valueString(Object object) { + + if (object instanceof List) { + List files = (List)object; + Object obj = files.get(0); + if (obj instanceof File) { + object = files.toArray(new File[files.size()]); + } else + if (obj instanceof String) { + object = files.toArray(new String[files.size()]); + } else { + String value = files.get(0).toString(); + for (int i = 1; i < files.size(); ++i) { + value = value + ", " + files.get(i).toString(); + } + return value; + } + } + + String value = null; + if (object instanceof File[]) { + File[] files = (File[])object; + value = files[0].getAbsolutePath(); + for (int i = 1; i < files.length; ++i) { + value = value + ", " + files[i].getAbsolutePath(); + } + } else + if (object instanceof File) { + File file = (File)object; + value = file.getAbsolutePath(); + } else + if (object instanceof String[]) { + String[] files = (String[])object; + value = files[0]; + for (int i = 1; i < files.length; ++i) { + value = value + ", " + files[i]; + } + } else + if (object instanceof String) { + String file = (String)object; + value = file; + } + return value; + } + + /** + *Getter method for selected. + */ + public File getSelected() { + return selected; + } + + /** + *Setter method for selected. + */ + public void setSelected(File selected) { + this.selected = selected; + } + + /** + *Getter method for folderName. + */ + public String getFolderName() { + + if (selected != null) { + return valueString(selected); + } else return null; + + } + + /** + * Summary message for Validator exception. + */ + public String getSummaryMsg() { + return MessageUtil.getMessage("chooseruploader_summary"); + } + + /** + * Checks for errors on page. + */ + public boolean isErrorsOnPage() { + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) >= 0) { + return true; + } + return false; + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + + selected = null; + return IndexBackingBean.INDEX_ACTION; + } + + /** + * Action handler when navigating to the chooser uploader example index. + */ + public String showUploaderIndex() { + + selected = null; + return "showChooserUploader"; + } +} + diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/common/ClientSniffer.java b/samples/woodstock/src/com/sun/webui/jsf/example/common/ClientSniffer.java new file mode 100644 index 0000000..69fd113 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/common/ClientSniffer.java @@ -0,0 +1,539 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.common; + +import java.util.Map; +import java.util.StringTokenizer; + +import javax.faces.context.FacesContext; + + +/** + * This utility class parses the user agent of a HttpServletRequest + * object to determine browser type, version, and platform. + *

    + * The code of this utility class is based on "The + * Ultimate JavaScript Client Sniffer", version 3.03 which is located + * at the following URL. + *

    + * http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html + *

    + * Usage Example: + *

    + * FacesContext context = FacesContext.getCurrentInstance();
    + * ClientSniffer cs = new ClientSniffer(context);
    + *
    + * String stylesheet = CCStyle.IE6_UP_CSS;
    + *
    + * if (isIe6up()) {
    + *     stylesheet = CCStyle.IE6_UP_CSS;
    + * } else if (isIe5up()) {
    + *     stylesheet = CCStyle.IE5_UP_CSS;
    + * } else if (isNav6up()) {
    + *     stylesheet = CCStyle.NS6_UP_CSS;
    + * } else if (isNav4up() && isWin()) {
    + *     stylesheet = CCStyle.NS4_WIN_CSS;
    + * } else if (isNav4up() && isSun()) {
    + *     stylesheet = CCStyle.NS4_SOL_CSS;
    + * }
    + * 

    + * + * @version 1.10 02/06/04 + * @author Sun Microsystems, Inc. + */ +public class ClientSniffer { + // User Agent Headers (DON'T DELETE). + // + // Windows 2000 + // ------------ + // + // IE 5.0 Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) + // Netscape 4.7 Mozilla/4.7 [en] (WinNT; U) + // Netscape 6.2.1 mozilla/5.0 (windows; u; win98; en-us; rv:0.9.4) + // gecko/20011128 netscape6/6.2.1 + // Netscape 7.02 Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; + // rv:1.0.2) Gecko/20030208 Netscape/7.02 + // Netscape 7.1 Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) + // Gecko/20030624 Netscape/7.1 (ax) + // Mozilla 1.4 Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) + // Gecko/20030624 + // + // SunOS + // ----- + // + // Netscape 4.78 Mozilla/4.78 [en] (X11; U; SunOS 5.10 sun4u) + // Netscape 6.2.1 mozilla/5.0 (x11; u; sunos sun4u; en-us; rv:0.9.4) + // gecko/20011206 netscape6/6.2.1 + // Netscape 6.2.2 Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:0.9.4.1) + // Gecko/20020406 Netscape6/6.2.2 + // Netscape 7.0 Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.0.1) + // Gecko/20020920 Netscape/7.0 + // Mozilla 1.1 Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.1) + // Gecko/20020827 + // HotJava 1.0.1 HotJava/1.0.1/JRE1.1.3 + // Generic Profile/MIDP-1.0 Configuration/CLDC-1.0 + + // User agent. + private String agent = null; + + // User agent major version number. + private int major = -1; + + /** + * Default constructor. + * + * @param context FacesContext which should be used to + * extract the user agent. + */ + public ClientSniffer(FacesContext context) { + String version = null; + setUserAgent(context); + agent = getUserAgent(); + + // Parse user agent. + if (agent != null) { + + StringTokenizer st = new StringTokenizer(agent, "/"); + + // Parse out user agent name. + if (st.hasMoreTokens()) { + st.nextToken(); + } + + // Get user agent version number. + if (st.hasMoreTokens()) { + version = st.nextToken(); + } + + // Remove white space & extra info. + st = new StringTokenizer(version); + + if (st.hasMoreTokens()) { + version = st.nextToken(); + } + } + + // Parse user agent major version number. + if (version != null) { + StringTokenizer st = new StringTokenizer(version, "."); + + if (st.hasMoreTokens()) { + try { + major = Integer.parseInt(st.nextToken()); + } catch (NumberFormatException ex) { + // Ignore + } + } + } + } + + /** + *

    This method gets an instance of this class associated with the + * given FacesContext. It will look in the request scope + * to see if an instance already exists, if not, it will create + * one.

    + * + * @param context The FacesContext + * + * @return A ClientSniffer instance. + */ + public static ClientSniffer getInstance(FacesContext context) { + // Look for a cached one + Map requestMap = context.getExternalContext().getRequestMap(); + ClientSniffer sniffer = (ClientSniffer) requestMap.get("__sniffer"); + + if (sniffer == null) { + // Not yet created, create one + sniffer = new ClientSniffer(context); + requestMap.put("__sniffer", sniffer); + } + + // Return the sniffer + return sniffer; + } + + /** + *

    This method initializes the user agent via the supplied + * FacesContext. It will use the + * ExternalContext to get at the request header Map. + * It will use this Map to obtain the value for + * USER-AGENT.

    + * + * @param context The FacesContext + */ + protected void setUserAgent(FacesContext context) { + Map headerMap = context.getExternalContext().getRequestHeaderMap(); + if(null != headerMap) { + agent = (String) headerMap.get("USER-AGENT"); + if(null != agent) { + agent = agent.toLowerCase(); + } + } + } + + /** + * Get the user agent. + * + * @return The user agent. + */ + public String getUserAgent() { + return agent; + } + + /** + * Get the user agent major version number. + * + * @return The user agent major version number or + * -1 if the version number was not retrieved. + */ + public int getUserAgentMajor() { + return major; + } + + /** + * Test if the user agent was generated on Windows platform. + * + * @return true or false + */ + public boolean isWin() { + boolean result = false; + + if ((agent != null) && ((agent.indexOf("win") != -1) + || (agent.indexOf("16bit") != -1))) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated on Sun platform. + * + * @return true or false + */ + public boolean isSun() { + boolean result = false; + + if ((agent != null) && (agent.indexOf("sunos") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Gecko engine. + * + * @return true or false + */ + public boolean isGecko() { + boolean result = false; + + if ((agent != null) && (agent.indexOf("gecko") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator. + * + * @return true or false + */ + public boolean isNav() { + boolean result = false; + + if ((agent != null) + && (agent.indexOf("mozilla") != -1) + && (agent.indexOf("spoofer") == -1) + && (agent.indexOf("compatible") == -1) + && (agent.indexOf("opera") == -1) + && (agent.indexOf("webtv") == -1) + && (agent.indexOf("hotjava") == -1)) { + // The header for Netscape 4.x is similar to the header + // for the Mozilla browser; however, Netscape 4.x does not + // implement the Gecko engine. + if (!(isGecko() && (agent.indexOf("netscape") == -1))) { + result = true; + } + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator, + * version 4.x. + * + * @return true or false + */ + public boolean isNav4() { + boolean result = false; + + if (isNav() && (major == 4)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator, + * version 4.x or above. + * + * @return true or false + */ + public boolean isNav4up() { + boolean result = false; + + if (isNav() && (major >= 4)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator, + * version 6.x. + * + * @return true or false + */ + public boolean isNav6() { + boolean result = false; + if (isNav() && (major == 5) && (null != agent) && + (agent.indexOf("netscape6") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator, + * version 6.x or above. + * + * @return true or false + */ + public boolean isNav6up() { + boolean result = false; + + if (isNav() && major >= 5) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator, + * version 7.x. + * + * @return true or false + */ + public boolean isNav7() { + boolean result = false; + if (isNav() && major == 5 && (null != agent) + && (agent.indexOf("netscape/7") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator, + * version 7.0. + * + * @return true or false + */ + public boolean isNav70() { + boolean result = false; + if (isNav() && major == 5 && (null != agent) + && (agent.indexOf("netscape/7.0") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Navigator, + * version 7.x or above. + * + * @return true or false + */ + public boolean isNav7up() { + boolean result = false; + + if (isNav() && (major >= 5) && !isNav4() && !isNav6()) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer. + * + * @return true or false + */ + public boolean isIe() { + boolean result = false; + + if ((agent != null) + && (agent.indexOf("msie") != -1) + && (agent.indexOf("opera") == -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 3.x. + * + * @return true or false + */ + public boolean isIe3() { + boolean result = false; + + if (isIe() && (major < 4)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 4.x. + * + * @return true or false + */ + public boolean isIe4() { + boolean result = false; + if (isIe() && (major == 4) && (null != agent) + && (agent.indexOf("msie 4") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 5.x. + * + * @return true or false + */ + public boolean isIe5() { + boolean result = false; + if (isIe() && (major == 4) && (null != agent) && (agent.indexOf("msie 5") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 5.x or above. + * + * @return true or false + */ + public boolean isIe5up() { + boolean result = false; + + if (isIe() && !isIe3() && !isIe4()) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 6.x. + * + * @return true or false + */ + public boolean isIe6() { + boolean result = false; + if (isIe() && (major == 4) && (null != agent) && (agent.indexOf("msie 6") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 7.x. + * + * @return true or false + */ + public boolean isIe7() { + boolean result = false; + if (isIe() && (major == 4) && (null != agent) && (agent.indexOf("msie 7") != -1)) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 6.x or above. + * + * @return true or false + */ + public boolean isIe6up() { + boolean result = false; + + if (isIe() && !isIe3() && !isIe4() && !isIe5()) { + result = true; + } + + return result; + } + + /** + * Test if the user agent was generated by Internet Explorer, + * version 7.x or above. + * + * @return true or false + */ + public boolean isIe7up() { + boolean result = false; + + if (isIe() && !isIe3() && !isIe4() && !isIe5() && !isIe6() ) { + result = true; + } + + return result; + } + +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/common/MessageUtil.java b/samples/woodstock/src/com/sun/webui/jsf/example/common/MessageUtil.java new file mode 100644 index 0000000..e95c45f --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/common/MessageUtil.java @@ -0,0 +1,116 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.common; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import javax.faces.context.FacesContext; + +/** + * Factory class for retrieving server-side i18n messages for the Java ES(tm) + * Monitoring Console within the JSF framework. This class does not override + * all methods in com.sun.webui.jsf.util.MessageUtil; it merely provides a few + * commonly used methods for getting resources using the Resources.properties + * files for this web application. + * + * @version 1.3 10/10/05 + * @author Sun Microsystems, Inc. + */ +public class MessageUtil { + /** The ResourceBundle basename for this web app. */ + static final public String BASENAME = "com.sun.webui.jsf.example.resources.Resources"; + + /** Get a message from the application's resource file. */ + static public String getMessage(String key) { + return getMessage(key, (Object[]) null); + } + + /** Get a formatted message from the application's resource file. */ + static public String getMessage(String key, String arg) { + Object[] args = { + arg + }; + return getMessage(key, args); + } + + /** Get a formatted message from the application's resource file. */ + static public String getMessage(String key, Object[] args) { + if (key == null) { + return key; + } + + ResourceBundle bundle = ResourceBundle.getBundle(BASENAME, getLocale()); + if (bundle == null) { + throw new NullPointerException("Could not obtain resource bundle"); + } + + String message = null; + try { + message = bundle.getString(key); + } catch (MissingResourceException e) { + } + + return getFormattedMessage((message != null) ? message : key, args); + } + + /** + * Format message using given arguments. + * + * @param message The string used as a pattern for inserting arguments. + * @param args The arguments to be inserted into the string. + */ + static protected String getFormattedMessage(String message, Object args[]) { + if ((args == null) || (args.length == 0)) { + return message; + } + + String result = null; + try { + MessageFormat mf = new MessageFormat(message); + result = mf.format(args); + } catch (NullPointerException e) { + } + + return (result != null) ? result : message; + } + + /** Get locale from the FacesContext object. */ + protected static Locale getLocale() { + FacesContext context = FacesContext.getCurrentInstance(); + if (context == null) { + return Locale.getDefault(); + } + + // context.getViewRoot() may not have been initialized at this point. + Locale locale = null; + if (context.getViewRoot() != null) { + locale = context.getViewRoot().getLocale(); + } + + return (locale != null) ? locale : Locale.getDefault(); + } + +} // MessageUtil diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/common/UserData.java b/samples/woodstock/src/com/sun/webui/jsf/example/common/UserData.java new file mode 100644 index 0000000..fc56162 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/common/UserData.java @@ -0,0 +1,51 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.common; + +import com.sun.data.provider.TableDataProvider; +import com.sun.data.provider.impl.ObjectArrayDataProvider; + +import java.util.List; + +/** + * This class contains data provider. + */ +public class UserData { + + /** Data provider. */ + private TableDataProvider provider = null; + + /** Default constructor. */ + public UserData() { + } + + /** Construct an instance using given Object array. */ + public UserData(Object[] array) { + provider = new ObjectArrayDataProvider(array); + } + + /** Get data provider. */ + public TableDataProvider getDataProvider() { + return provider; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/commontask/commonTaskBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/commontask/commonTaskBean.java new file mode 100644 index 0000000..19e3448 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/commontask/commonTaskBean.java @@ -0,0 +1,39 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +package com.sun.webui.jsf.example.commontask; + +import com.sun.webui.jsf.example.index.IndexBackingBean; + +public class commonTaskBean { + + /** Creates a new instance of commonTaskBean */ + public commonTaskBean() { + } + + public String taskAction() { + return "task"; + } + + public String showExampleIndex() { + return IndexBackingBean.INDEX_ACTION; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/editablelist/EditableListBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/editablelist/EditableListBackingBean.java new file mode 100644 index 0000000..94e7bc7 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/editablelist/EditableListBackingBean.java @@ -0,0 +1,236 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.editablelist; + +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; +import javax.faces.event.ValueChangeEvent; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; +import java.io.Serializable; + +/** + * Backing Bean for editable list example. + */ +public class EditableListBackingBean implements Serializable { + + // Holds value for property roles. + private String[] roles; + + // Holds value for listTopChkBox property. + private boolean listTopChkBox = true; + + // Holds value for sortedChkBox property. + private boolean sortedChkBox = true; + + // Holds value for listTopBottom. + private boolean listTopBottom = true; + + // Holds value for sortedList. + private boolean sortedList = true; + + + + /** Creates a new instance of EfitableListBackingBean */ + public EditableListBackingBean() { + roles = new String[5]; + + roles[0] = "Cron Management"; + roles[1] = "DHCP Management"; + roles[2] = "Log Management"; + roles[3] = "Mail Management"; + roles[4] = "Network Management"; + + } + + /** + * this method assigns value to listonTop + * property of editable list tag. + */ + public boolean getListTopBottom() { + + return listTopBottom; + + } + + /** + * this method assigns value to sorted + * property of editablelist tag. + */ + public boolean getSortedList() { + + return sortedList; + } + + /** valueChangelistener for checkbox that sets list on top property. */ + public void listOnToplistener(ValueChangeEvent event) { + + Boolean newValue = (Boolean) event.getNewValue(); + if (newValue != null + && newValue.booleanValue()) { + listTopBottom = true; + } else { + listTopBottom = false; + } + + } + + /** valueChangelistener for checkbox that sets sorted property. */ + public void sortedlistener(ValueChangeEvent event) { + + Boolean newValue = (Boolean) event.getNewValue(); + if (newValue != null + && newValue.booleanValue()) { + sortedList = true; + } else { + sortedList = false; + } + + } + + /** getter method for property roles. */ + public String[] getRoles() { + + return this.roles; + } + + /** Setter method for property roles. */ + public void setRoles(String[] roles) { + + this.roles = roles; + } + + /** Getter method for listTopChkBox property. */ + public boolean getListTopChkBox() { + return listTopChkBox; + } + + /** Getter method for sortedChkBox property. */ + public boolean getSortedChkBox() { + return sortedChkBox; + } + + /** Setter method for listTopChkBox property. */ + public void setListTopChkBox(boolean listTopChkBox) { + this.listTopChkBox = listTopChkBox; + } + + /** Setter method for sortedChkBox property. */ + public void setSortedChkBox(boolean sortedChkBox) { + this.sortedChkBox = sortedChkBox; + } + + /** validate method for role validation. */ + public void validate(FacesContext context, UIComponent component, + Object value) throws ValidatorException { + + String msgString = null; + FacesMessage msg = null; + String string = value.toString(); + + char[] characters = string.toCharArray(); + for (int counter = 0; counter < characters.length; ++counter) { + if (!Character.isLetter(characters[counter]) && + characters[counter] != ' ') { + msgString = MessageUtil. + getMessage("editablelist_string"); + msg = new FacesMessage(msgString); + throw new ValidatorException(msg); + } + } + + } + + /** list validator that checks for number of list items. */ + public void validateList(FacesContext context, UIComponent component, + Object value) throws ValidatorException { + + if (value instanceof String[]) { + String[] list = (String[]) value; + if (list.length < 5) { + String msgString = MessageUtil. + getMessage("editablelist_listvalidate"); + FacesMessage msg = new FacesMessage(msgString); + throw new ValidatorException(msg); + } + } + } + + /** + * Summary message for Validator exception. + */ + public String getSummaryMsg() { + return MessageUtil.getMessage("editablelist_summary"); + } + + /** + * Checks for errors on page. + */ + public boolean isErrorsOnPage() { + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) >= 0) { + return true; + } + return false; + } + + /** + * method to get edited roles for resultpage. + **/ + public String getEditedRoles() { + + if (roles == null) + return ""; + int i = 0; + StringBuffer editedRole = new StringBuffer(); + for (i = 0; i < roles.length - 1; ++i) { + editedRole.append(roles[i]); + editedRole.append(", "); + } + editedRole.append(roles[i]); + return editedRole.toString(); + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + + listTopChkBox = true; + sortedChkBox = true; + listTopBottom = true; + sortedList = true; + return IndexBackingBean.INDEX_ACTION; + } +} + diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/field/TextInputBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/field/TextInputBackingBean.java new file mode 100644 index 0000000..0bb50a2 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/field/TextInputBackingBean.java @@ -0,0 +1,301 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.field; + +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; + +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.model.OptionTitle; + +import com.sun.webui.jsf.component.DropDown; +import com.sun.webui.jsf.component.TextField; +import com.sun.webui.jsf.component.PasswordField; +import com.sun.webui.jsf.component.TextArea; + +import com.sun.webui.jsf.example.index.IndexBackingBean; +import com.sun.webui.jsf.example.common.MessageUtil; + +import java.io.Serializable; + +/** + * Backing bean for the Text Input example. + * + * Note that we must implement java.io.Serializable or + * javax.faces.component.StateHolder in case client-side + * state saving is used, or if server-side state saving is + * used with a distributed system. + */ +public class TextInputBackingBean implements Serializable { + + // Text input default value. + private static final String TEXTINPUT_DEFAULT_VALUE = + MessageUtil.getMessage("field_textFieldTitle"); + + // Text area default value. + private static final String TEXTAREA_DEFAULT_VALUE = + MessageUtil.getMessage("field_textAreaTitle"); + + /** Holds value of property textFieldValue. */ + private String textFieldValue = TEXTINPUT_DEFAULT_VALUE;; + + /** Holds value of property passwordValue. */ + private String passwordValue = ""; + + /** Holds value of property textAreaValue. */ + private String textAreaValue = TEXTAREA_DEFAULT_VALUE; + + /** Holds value of property testCaseOptions. */ + private Option[] testCaseOptions = null; + + /** Holds value of property textFieldDisabled. */ + private boolean textFieldDisabled = false; + + /** Holds value of property passwordDisabled. */ + private boolean passwordDisabled = false; + + /** Holds value of property textAreaDisabled. */ + private boolean textAreaDisabled = false; + + /** Default constructor */ + public TextInputBackingBean() { + testCaseOptions = new Option[6]; + testCaseOptions[0] = new OptionTitle( + MessageUtil.getMessage("field_testCaseTitle")); + testCaseOptions[1] = new Option("field_testCaseToggleTextFieldState", + MessageUtil.getMessage("field_testCaseToggleTextFieldState")); + testCaseOptions[2] = new Option("field_testCaseTogglePasswordState", + MessageUtil.getMessage("field_testCaseTogglePasswordState")); + testCaseOptions[3] = new Option("field_testCaseToggleTextAreaState", + MessageUtil.getMessage("field_testCaseToggleTextAreaState")); + testCaseOptions[4] = new Option("field_testCaseDisableAll", + MessageUtil.getMessage("field_testCaseDisableAll")); + testCaseOptions[5] = new Option("field_testCaseEnableAll", + MessageUtil.getMessage("field_testCaseEnableAll")); + } + + /** Get the value of the text field. */ + public String getTextFieldValue() { + return textFieldValue; + } + + /** Set the value of the text field. */ + public void setTextFieldValue(String textFieldValue) { + this.textFieldValue = textFieldValue; + } + + /** Get the value of the password field. */ + public String getPasswordValue() { + return passwordValue; + } + + /** Set the value of the password field. */ + public void setPasswordValue(String passwordValue) { + this.passwordValue = passwordValue; + } + + /** Get the value of the text area. */ + public String getTextAreaValue() { + return textAreaValue; + } + + /** Set the value of the text area. */ + public void setTextAreaValue(String textAreaValue) { + this.textAreaValue = textAreaValue; + } + + /** Return the array of test case options */ + public Option[] getTestCaseOptions() { + return testCaseOptions; + } + + /** Get the disabled state of the text field. */ + public boolean getTextFieldDisabled() { + return textFieldDisabled; + } + + /** Set the disabled state of the text field. */ + public void setTextFieldDisabled(boolean textFieldDisabled) { + this.textFieldDisabled = textFieldDisabled; + } + + /** Get the disabled state of the password field. */ + public boolean getPasswordDisabled() { + return passwordDisabled; + } + + /** Set the disabled state of the password field. */ + public void setPasswordDisabled(boolean passwordDisabled) { + this.passwordDisabled = passwordDisabled; + } + + /** Get the disabled state of the text area. */ + public boolean getTextAreaDisabled() { + return textAreaDisabled; + } + + /** Set the disabled state of the text area. */ + public void setTextAreaDisabled(boolean textAreaDisabled) { + this.textAreaDisabled = textAreaDisabled; + } + + /** Return the state result for text field. */ + public String getTextFieldResult() { + Object[] args = new Object[3]; + args[0] = MessageUtil.getMessage("field_textFieldTitle"); + if (getTextFieldDisabled()) { + args[1] = MessageUtil.getMessage("field_disabled"); + } else { + args[1] = MessageUtil.getMessage("field_enabled"); + } + args[2] = getTextFieldValue(); + + return MessageUtil.getMessage("field_fieldResult", args); + } + + /** Return the state result for password. */ + public String getPasswordResult() { + Object[] args = new Object[3]; + args[0] = MessageUtil.getMessage("field_passwordTitle"); + if (getPasswordDisabled()) { + args[1] = MessageUtil.getMessage("field_disabled"); + } else { + args[1] = MessageUtil.getMessage("field_enabled"); + } + args[2] = getPasswordValue(); + + return MessageUtil.getMessage("field_fieldResult", args); + } + + /** Return the state result for text area. */ + public String getTextAreaResult() { + Object[] args = new Object[3]; + args[0] = MessageUtil.getMessage("field_textAreaTitle"); + if (getTextAreaDisabled()) { + args[1] = MessageUtil.getMessage("field_disabled"); + } else { + args[1] = MessageUtil.getMessage("field_enabled"); + } + args[2] = getTextAreaValue(); + + return MessageUtil.getMessage("field_fieldResult", args); + } + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + // Reset when leaving the example. + textFieldValue = TEXTINPUT_DEFAULT_VALUE; + passwordValue = ""; + textAreaValue = TEXTAREA_DEFAULT_VALUE; + disable(false); + + return IndexBackingBean.INDEX_ACTION; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Listeners + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action listener for the test case dropdown menu. */ + public void processMenuSelection(ActionEvent e) { + DropDown dropDown = (DropDown) e.getComponent(); + String selected = (String) dropDown.getSelected(); + FacesContext context = FacesContext.getCurrentInstance(); + TextField textField = (TextField) context.getViewRoot().findComponent( + "form:textField"); + PasswordField password = + (PasswordField) context.getViewRoot().findComponent( + "form:password"); + TextArea textArea = (TextArea) context.getViewRoot().findComponent( + "form:textArea"); + + // Since the action is immediate, the components won't + // go through the Update Model phase. So, we need to explicitly set the + // state of the components and update the model object for the given action selected. + if (selected.equals("field_testCaseDisableAll")) { + textField.setDisabled(true); + password.setDisabled(true); + textArea.setDisabled(true); + disable(true); + + } else if (selected.equals("field_testCaseEnableAll")) { + textField.setDisabled(false); + password.setDisabled(false); + textArea.setDisabled(false); + disable(false); + } else if (selected.equals("field_testCaseToggleTextFieldState")) { + textField.setDisabled(!getTextFieldDisabled()); + setTextFieldDisabled(!getTextFieldDisabled()); + } else if (selected.equals("field_testCaseTogglePasswordState")) { + password.setDisabled(!getPasswordDisabled()); + setPasswordDisabled(!getPasswordDisabled()); + } else if (selected.equals("field_testCaseToggleTextAreaState")) { + textArea.setDisabled(!getTextAreaDisabled()); + setTextAreaDisabled(!getTextAreaDisabled()); + } + } + + /** Action listener for the preset button. */ + public void presetFields(ActionEvent e) { + // Sine the action is immediate, the text input components won't + // go through the Update Model phase. However, their submitted values + // get set in the Apply Request Value phase and these values are retained + // when the page is redisplayed. + // + // So, we need to explicitly erase the submitted values and then update + // the model object with initial values. + FacesContext context = FacesContext.getCurrentInstance(); + + TextField textField = (TextField) context.getViewRoot().findComponent( + "form:textField"); + textField.setSubmittedValue(null); + textField.setDisabled(false); + textFieldValue = TEXTINPUT_DEFAULT_VALUE; + + PasswordField password = + (PasswordField) context.getViewRoot().findComponent( + "form:password"); + password.setSubmittedValue(null); + password.setDisabled(false); + passwordValue = ""; + + TextArea textArea = (TextArea) context.getViewRoot().findComponent( + "form:textArea"); + textArea.setSubmittedValue(null); + textArea.setDisabled(false); + textAreaValue = TEXTAREA_DEFAULT_VALUE; + + disable(false); + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private Methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Helper method to set the disabled state of the input fields. */ + private void disable(boolean value) { + setTextFieldDisabled(value); + setTextAreaDisabled(value); + setPasswordDisabled(value); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/hyperlink/HyperlinkBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/hyperlink/HyperlinkBackingBean.java new file mode 100644 index 0000000..6a2f9bc --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/hyperlink/HyperlinkBackingBean.java @@ -0,0 +1,213 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.hyperlink; + +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; +import javax.faces.event.ValueChangeEvent; +import javax.faces.event.ActionEvent; + +import com.sun.webui.jsf.component.TextField; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; +import java.util.Date; +import java.io.*; + +/** + * Backing Bean for Hyperlink example. + */ +public class HyperlinkBackingBean implements Serializable { + + // Holds value for property userName. + private String userName = null; + + // Holds value for property linkDisable. + private boolean linkDisable = false; + + // Holds value for displayParam property. + private boolean displayParam = false; + + // Holds value for property date. + private String date = null; + + // Holds value for property linkOnoff. + private boolean linkOnoff = false; + + // Holds value for property enable hyperlink. + private boolean enableHyperlink = true; + + // Holds value for property disable hyperlink. + private boolean disableHyperlink = false; + + // String constant for disable button id. + private static String DISABLE_BUTTON_ID = + "hyperlinkForm:pageButtonsGroupBottom:disable"; + + /** Creates a new instance of HyperlinkBackingBean */ + public HyperlinkBackingBean() { + } + + /** Getter method for username property. */ + public String getUserName() { + return userName; + } + + /** Setter method for property userName */ + public void setUserName(String name) { + this.userName = name; + } + + /** + * this method assigns value to disabled + * property of hyperlink tag. + */ + public boolean getLinkOnoff() { + return linkOnoff; + } + + /** + * this method returns current date. + */ + public String getStartDate() { + return (new Date()).toString(); + } + + /** + * this method returns param value. + */ + public String getParamValue() { + date = (String) FacesContext.getCurrentInstance(). + getExternalContext().getRequestParameterMap(). + get("dateParam"); + return date; + } + + /** + * this method returns boolean for visible attribute of + * staticText and label tag. + */ + public boolean getRenderParam() { + date = (String) FacesContext.getCurrentInstance(). + getExternalContext().getRequestParameterMap(). + get("dateParam"); + + if (date != null) { + return true; + } + return false; + } + + /** Action listener for the immediate hyperlink. */ + public void immediateAction(ActionEvent ae) { + // Since the action is immediate, the textfield component won't + // go through the Update Model phase and the model object won't + // get updated with the submitted value. So, we need to update the + // model here so that it reflects the new value. + FacesContext context = FacesContext.getCurrentInstance(); + TextField textField= (TextField) context.getViewRoot().findComponent( + "hyperlinkForm:nameField"); + userName = (String) textField.getSubmittedValue(); + } + + /** Action handler. */ + public String nextPage() { + return "resultHyperlink"; + } + + /** + * Summary message for Validator exception. + */ + public String getSummaryMsg() { + return MessageUtil.getMessage("hyperlink_summary"); + } + + /** + * getter method for enabling hyperlink. + */ + public boolean getEnableHyperlink() { + return enableHyperlink; + } + + /** + * getter method for disabling hyperlink. + */ + public boolean getDisableHyperlink() { + return disableHyperlink; + } + + /** + * Detail message for Validator exception. + */ + public String getDetailMsg() { + return MessageUtil.getMessage("hyperlink_detail"); + } + /** + * Checks for errors on page. + */ + public boolean isErrorsOnPage() { + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) >= 0) { + return true; + } + return false; + } + + /** Action listener for the disable/enable hyperlink button. */ + public void onOffbuttonAction(ActionEvent ae) { + + FacesContext context = FacesContext.getCurrentInstance(); + String clientId = ae.getComponent().getClientId(context); + if (clientId != null && clientId.equals(DISABLE_BUTTON_ID)) { + linkOnoff = true; + enableHyperlink = false; + disableHyperlink = true; + } else { + linkOnoff = false; + enableHyperlink = true; + disableHyperlink = false; + } + + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + + userName = null; + linkOnoff = false; + enableHyperlink = true; + disableHyperlink = false; + return IndexBackingBean.INDEX_ACTION; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/index/AppAction.java b/samples/woodstock/src/com/sun/webui/jsf/example/index/AppAction.java new file mode 100644 index 0000000..c7c6ff5 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/index/AppAction.java @@ -0,0 +1,47 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.index; + +/** + * This class is used to get the action value of an example app. + */ +public class AppAction { + + private String action; + + /** + * Construct a new instance of AppAction. + * + * @param action The example app action + */ + public AppAction(String action) { + this.action = action; + } + + /** + * Return the action value + */ + public String action() { + return action; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/index/AppData.java b/samples/woodstock/src/com/sun/webui/jsf/example/index/AppData.java new file mode 100644 index 0000000..43ab612 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/index/AppData.java @@ -0,0 +1,90 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.index; + +import com.sun.webui.jsf.example.index.AppAction; + +/** + * A convenient class to wrap data about a given example. + */ +public class AppData { + + /** The example app name */ + private String name; + + /** The concepts illustrated by this example */ + private String concepts; + + /** The example app action */ + private String appAction; + + /** + * Array of file names that will have source code + * links for this example + */ + private String[] files; + + /** + * Accepts info necessary to describe the given + * example. + * + * @param name The name of the example + * @param concepts The concepts illustrated by this example + * @param appAction The example app action + * @param files Array of file names for this example + */ + public AppData(String name, String concepts, String appAction, String[] files) { + this.name = name; + this.concepts = concepts; + this.appAction = appAction; + this.files = files; + } + + /** + * Get the name of the example + */ + public String getName() { + return name; + } + + /** + * Get the concepts illustrated by this example + */ + public String getConcepts() { + return concepts; + } + + /** + * Get AppAction. + */ + public AppAction getAppAction() { + return new AppAction(appAction); + } + + /** + * Get array of files for this example + */ + public String[] getFiles() { + return files; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/index/IndexBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/index/IndexBackingBean.java new file mode 100644 index 0000000..e11b91f --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/index/IndexBackingBean.java @@ -0,0 +1,224 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.index; + +import com.sun.webui.jsf.example.index.TableData; +import com.sun.webui.jsf.example.index.AppData; +import com.sun.webui.jsf.example.common.MessageUtil; + +import com.sun.webui.jsf.component.Hyperlink; +import com.sun.webui.jsf.component.TableColumn; +import com.sun.webui.jsf.component.Markup; + +import com.sun.data.provider.TableDataProvider; +import com.sun.data.provider.impl.ObjectArrayDataProvider; + +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.component.UIParameter; + +import java.util.ArrayList; +import java.io.Serializable; + +import com.sun.webui.jsf.example.util.ExampleUtilities; + + +/** + * This bean class provides data to the index page table + * in the example app. + */ +public class IndexBackingBean implements Serializable { + + // Hyperlink id + private static final String HYPERLINK_ID = "link"; + + // The outcome strings used in the faces config file + private static final String SHOWCODE_ACTION = "showCode"; + public static final String INDEX_ACTION = "showIndex"; + + // TableColumn component. + private TableColumn tableColumn = null; + + // Table data + private TableData tableData = null; + + // Table provider + private TableDataProvider provider = null; + + /** Default constructor. */ + public IndexBackingBean() { + tableData = new TableData(); + } + + /** + * Get table data provider + */ + public TableDataProvider getDataProvider() { + if (provider == null) { + provider = new ObjectArrayDataProvider(getTableData()); + } + return provider; + } + + /** + * Get table data + */ + public AppData[] getTableData() { + return tableData.data; + } + + /** + * Get tableColumn component + */ + public TableColumn getTableColumn() { + if (tableColumn == null) { + String id; + int maxLinks = 0; + int numFiles = 0; + + // create tableColumn + tableColumn = createTableColumn("col3", "index_filesHeader"); + + // Find the maximum number of hyperlinks that should be created + // by counting the number of files in the AppData array object. + AppData[] tableData = getTableData(); + for (int k = 0; k < tableData.length; k++) { + numFiles = tableData[k].getFiles().length; + if (numFiles > maxLinks) { + maxLinks = numFiles; + } + } + + // Create hyperlinks up to the maximum number of files + // in the AppData object. Use the "rendered" attribute + // of the hyperlink component to hide it if there are + // less links to show. + if (maxLinks > 0) { + for (int i = 0; i < maxLinks; i++) { + id = HYPERLINK_ID + "_" + i; + + // Create hyperlinks for each file in an example app + // to show the source code + Hyperlink hyperlink = createHyperlink(id, + "#{data.value.files["+ i + "]}", + "#{IndexBean.action}", + "#{data.value.files[" + i + "]}"); + + // The hyperlink is an ActionSource component + // which should be marked immediate by default. + hyperlink.setImmediate(true); + + // Don't display the link if no file name exists. + ExampleUtilities.setValueExpression(hyperlink, "rendered", + "#{data.value.files["+ i + "] != null}"); + + // Add new lines between the hyperlinks. + Markup markup = createMarkup("br", true); + ExampleUtilities.setValueExpression(markup, "rendered", + "#{data.value.files["+ i + "] != null}"); + + tableColumn.getChildren().add(hyperlink); + tableColumn.getChildren().add(markup); + } + } + } + return tableColumn; + } + + /** + * Set tableColumn component. + * + * @param tableColumn The TableColumn component + */ + public void setTableColumn(TableColumn tableColumn) { + this.tableColumn = tableColumn; + } + + /** + * Return the string used for hyperlink action. + */ + public String action() { + return new String(SHOWCODE_ACTION); + } + + /** + * Return the string used for breadcrumbs action. + */ + public String showIndex() { + return new String(INDEX_ACTION); + } + + /** + * Helper method to create table column + * + * @param id The component id. + * @param header The component header text. + */ + private TableColumn createTableColumn(String id, String header) { + TableColumn col = new TableColumn(); + col.setId(id); + col.setHeaderText(MessageUtil.getMessage(header)); + return col; + } + + /** + * Helper method to create hyperlink. + * + * @param id The component id. + * @param text Value binding expression for text. + * @param action Method binding expression for action. + * @param parameter Value binding expression for parameter. + */ + private Hyperlink createHyperlink(String id, String text, String action, + String parameter) { + // Get hyperlink. + Hyperlink hyperlink = new Hyperlink(); + hyperlink.setId(id); // Set id. + ExampleUtilities.setValueExpression(hyperlink, + "text", text); // Set text. + ExampleUtilities.setMethodExpression(hyperlink, + "actionExpression", action); // Set action. + + // Create paramerter. + UIParameter param = new UIParameter(); + param.setId(id + "_param"); + param.setName("param"); + ExampleUtilities.setValueExpression(param, + "value", parameter); // Set parameter. + hyperlink.getChildren().add(param); + + return hyperlink; + } + + /** + * Helper method to create markup + */ + private Markup createMarkup(String tag, boolean singleton) { + // Get markup. + Markup markup = new Markup(); + markup.setTag(tag); + markup.setSingleton(singleton); + return markup; + } + +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/index/JavaHtmlConverter.java b/samples/woodstock/src/com/sun/webui/jsf/example/index/JavaHtmlConverter.java new file mode 100644 index 0000000..15b53e1 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/index/JavaHtmlConverter.java @@ -0,0 +1,427 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.index; + +import java.io.*; +import java.util.*; + +/** + * JavaHtmlConverter converts the contents of a Java source code file to HTML. + * The HTML generated display line numbers and color codes Java keywords (or + * at least those in the private keyword array field). + * + * @author Sun Microsystems, Inc. + */ +public class JavaHtmlConverter extends Object { + /** + * Accepts a Reader object containing the Java source code to markup and + * a Writer object that will be used to output the HTML to display the + * source. + * + * @param in Contains the Java source code + * @param out Used to output the HTML displaying the source + */ + public static void convert(Reader in, Writer out) + throws IOException { + convert(in, out, false, true, -1, -1); + } + + /** + * Accepts a Reader object containing the Java source code to markup and + * a Writer object that will be used to output the HTML to display the + * source. Also accepts a boolean indicating if the HTML generated will + * be embedded withing an enclosing HTML page, or will be standalone. If + * embeddable is false, the HTML header and footer will be written to out. + * Otherwise, no header or footer are written. + * + * @param in Contains the Java source code + * @param out Used to output the HTML displaying the source + * @param embeddable Indicates if the HTML output will be embedded inside + * an HTML page. If false, the HTML header & footer will be written + * to the Writer object. + */ + public static void convert(Reader in, Writer out, boolean embeddable) + throws IOException { + convert(in, out, embeddable, true, -1, -1); + } + + /** + * Accepts a Reader object containing the Java source code to markup and + * a Writer object that will be used to output the HTML to display the + * source. Also accepts a boolean indicating if the HTML generated will + * be embedded withing an enclosing HTML page, or will be standalone. If + * embeddable is false, the HTML header and footer will be written to out. + * Otherwise, no header or footer are written. The highlightKeywords param + * should be set to true if color coding of Java keywords is desired. + * + * @param in Contains the Java source code + * @param out Used to output the HTML displaying the source + * @param embeddable Indicates if the HTML output will be embedded inside + * an HTML page. If false, the HTML header & footer will be written + * to the Writer object. + * @param highlightKeywords Indicates if Java keyword color coding / + * highlighting is desired + */ + public static void convert(Reader in, Writer out, boolean embeddable, + boolean highlightKeywords) + throws IOException { + + convert(in, out, embeddable, highlightKeywords, -1, -1); + } + + /** + * Accepts a Reader object containing the Java source code to markup and + * a Writer object that will be used to output the HTML to display the + * source. Also accepts a boolean indicating if the HTML generated will + * be embedded withing an enclosing HTML page, or will be standalone. If + * embeddable is false, the HTML header and footer will be written to out. + * Otherwise, no header or footer are written. The highlightKeywords param + * should be set to true if color coding of Java keywords is desired. This + * constructor can also be used to highlight a certain range of lines in the + * markup generated for the Java source. The desired lines to highlight are + * specified via the startLineHighlight and endLineHighlight int params. + * + * @param in Contains the Java source code + * @param out Used to output the HTML displaying the source + * @param embeddable Indicates if the HTML output will be embedded inside + * an HTML page. If false, the HTML header & footer will be written + * to the Writer object. + * @param highlightKeywords Indicates if Java keyword color coding / + * highlighting is desired + * @param startLineHighlight The first line of the Java source that should + * be highlighted from the rest + * @param endLineHighlight The last line of the Java source that should be + * highlighted from the rest + */ + public static void convert(Reader in, Writer out, + boolean embeddable, boolean highlightKeywords, + int startLineHighlight, int endLineHighlight) + throws IOException { + + int lineNumber = 1; + + StringBuffer buf = new StringBuffer(2048); + int c = 0; + int kwl = 0; + int bufl = 0; + char ch = 0; + char lastChar; + + final int STATE_NORMAL = 0; + final int STATE_STRING = 1; + final int STATE_CHAR = 2; + final int STATE_COMMENT_LINE = 3; + final int STATE_COMMENT = 4; + + // Keep a state flag + int state = STATE_NORMAL; + + // Write the header + if (!embeddable) { + out.write("\r\n\r\n"); + out.write("\r\n\r\n\r\n"); + } + + out.write("
    \r\n");
    +	out.write(getLineNumberReference(
    +	    lineNumber++, startLineHighlight, endLineHighlight));
    +	
    +	while (c != -1) {
    +	    c = in.read();
    +	    lastChar = ch;
    +	    ch = c >= 0 ? (char) c : 0;
    +
    +	    if (state == STATE_NORMAL) {
    +		if (kwl == 0 && Character.isJavaIdentifierStart(ch) 
    +		    && !Character.isJavaIdentifierPart(lastChar)
    +		    || kwl > 0 && Character.isJavaIdentifierPart(ch)) {
    +
    +		    buf.append(ch);
    +		    bufl++;
    +		    kwl++;
    +		    continue;
    +		} else if (kwl > 0) {
    +		    String kw = buf.toString().
    +			substring(buf.length() - kwl);
    +		    if (keywordList.contains(kw) && 
    +			highlightKeywords) {
    +			buf.insert(buf.length() - kwl, 
    +			    "");
    +			buf.append("");
    +		    }
    +		    kwl = 0;
    +		}
    +	    }
    +
    +	    switch (ch) {
    +		case '&':
    +		    buf.append("&");
    +		    bufl++;
    +		    break;
    +			
    +		case '\"':
    +		    buf.append(""");
    +		    bufl++;
    +		    if (state == STATE_NORMAL) {
    +			buf.insert(buf.length() - 6, 
    +			    "");
    +			state = STATE_STRING;
    +		    } else if (state == STATE_STRING && lastChar != '\\') {
    +			buf.append("");
    +			state = STATE_NORMAL;
    +		    }
    +			
    +		    break;
    +			
    +		case '\'':
    +		    buf.append("\'");
    +		    bufl++;
    +		    if (state == STATE_NORMAL)
    +			state = STATE_CHAR;
    +		    else if (state == STATE_CHAR && lastChar != '\\')
    +			state = STATE_NORMAL;
    +
    +		    break;
    +			
    +		case '\\':
    +		    buf.append("\\");
    +		    bufl++;
    +		    if (lastChar == '\\' && 
    +		       (state == STATE_STRING || state == STATE_CHAR))
    +			lastChar = 0;
    +
    +		    break;
    +			
    +		case '/':
    +		    buf.append("/");
    +		    bufl++;
    +		    if (state == STATE_COMMENT && lastChar == '*') {
    +			buf.append("");
    +			state = STATE_NORMAL;
    +		    }
    +		    if (state == STATE_NORMAL && lastChar == '/') {
    +			buf.insert(buf.length() - 2, 
    +			    "");
    +			state = STATE_COMMENT_LINE;
    +		    }
    +
    +		    break;
    +			
    +		case '*':
    +		    buf.append("*");
    +		    bufl++;
    +		    if (state == STATE_NORMAL && lastChar == '/') {
    +			buf.insert(buf.length() - 2, 
    +			    "");
    +			state = STATE_COMMENT;
    +		    }
    +
    +		    break;
    +			
    +		case '<':
    +		    buf.append("<");
    +		    bufl++;
    +		    break;
    +			
    +		case '>':
    +		    buf.append(">");
    +		    bufl++;
    +		    break;
    +			
    +		case '\t':
    +		    int n = bufl / tabsize * tabsize + tabsize;
    +		    while (bufl < n) {
    +			buf.append(' ');
    +			bufl++;
    +		    }
    +
    +		    break;
    +			
    +		case '\r':
    +		    // Ignore; we will deal with these
    +		    // as part of the '\n' processing
    +		    break;
    +			
    +		case '\n':
    +		    if (state == STATE_COMMENT_LINE) {
    +			buf.append("");
    +			state = STATE_NORMAL;
    +		    }
    +			
    +		    buf.append('\r');
    +		    buf.append(ch);
    +		    buf.append(getLineNumberReference(
    +			lineNumber++, startLineHighlight, endLineHighlight));
    +			
    +		    if (buf.length() >= 1024) {
    +			out.write(buf.toString());
    +			buf.setLength(0);
    +		    }
    +
    +		    bufl = 0;
    +
    +		    if (kwl != 0)
    +			kwl = 0; // This should never execute
    +		    if (state != STATE_NORMAL && state != STATE_COMMENT)
    +			state = STATE_NORMAL; // Syntax Error
    +
    +		    break;
    +			
    +		case 0:
    +		    if (c < 0) {
    +			if (state == STATE_COMMENT_LINE) {
    +			    buf.append("");
    +			    state = STATE_NORMAL;
    +			}
    +			out.write(buf.toString());
    +			buf.setLength(0);
    +			bufl = 0;
    +			if (state == STATE_COMMENT) {
    +			    // Syntax Error
    +			    buf.append("");
    +			    state = STATE_NORMAL;
    +			}
    +
    +			break;
    +		    }
    +			
    +		default:
    +		    bufl++;
    +		    buf.append(ch);
    +	    }
    +	}
    +
    +	out.write("
    "); + if (!embeddable) + out.write("\r\n\r\n"); + + out.flush(); + } + + /** + * Returns an anchor tag containg the necessary markup to highlight the + * given lineNumber. The given lineNumber must be between + * startLineHighlight and endLineHighlight or else its color will not + * be changed (it will not be highlighted). Note that this ONLY + * highlights the line number, not the entire line. + * + * @param lineNumber The line number to be highlighted + * @param startLineHighlight Minimum value for lineNumber + * @param endLineHighlight Maximum value for lineNumber + * @return String Contains the markup to display the highlighted line + * number + */ + private static String getLineNumberReference(int lineNumber, + int startLineHighlight, int endLineHighlight) { + String result = "= startLineHighlight && lineNumber < endLineHighlight) + result += highlightLineNumberColor; + else + result += lineNumberColor; + + result += "\">"; + + if (lineNumber < 10) + result += "   " + lineNumber; + else + if (lineNumber < 100) + result += "  " + lineNumber; + else + if (lineNumber < 1000) + result += " " + lineNumber; + else + if (lineNumber < 10000) + result += lineNumber; + + result += " "; + return result; + } + + // Class variables + + /** + * The words that will color coded in the HTML as Java keywords + */ + static final String[] keywords = { + "abstract", "default", "if", "private", "throw", + "boolean", "do", "implements", "protected", "throws", + "break", "double", "import", "public", "transient", + "byte", "else", "instanceof", "return", "try", + "case", "extends", "int", "short", "void", + "catch", "final", "interface", "static", "volatile", + "char", "finally", "long", "super", "while", + "class", "float", "native", "switch", + "const", "for", "new", "synchronized", + "continue", "goto", "package", "this" + }; + + /** + * Helper List to process the Java keywords array + */ + private static List keywordList = new ArrayList(keywords.length); + /** + * Size to use for syntax indenting in the HTML produced + */ + private static int tabsize = 8; + + // Note, without the hashmarks, JEditorPane doesn't understand these colors + /** + * Background color used for the HTML produced + */ + private static String backgroundColor = "#FFFFFF"; + /** + * Color used for normal text in the HTML produced + */ + private static String textColor = "#000000"; + /** + * Color used for keyword text in the HTML produced + */ + private static String keywordColor = "#0000F0"; + /** + * Color used for Java comment text in the HTML produced + */ + private static String commentColor = "#1E801E"; + /** + * Color used for Java String literals in the HTML produced + */ + private static String stringColor = "#007F7F"; + /** + * Color used for line number text in the HTML produced + */ + private static String lineNumberColor = "#C0C0C0"; + /** + * Color used to highlight line number text in the HTML produced + */ + private static String highlightLineNumberColor = "#FF0000"; + + // Static initialization + + static { + for (int i = 0; i < keywords.length; i++) + keywordList.add(keywords[i]); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/index/ShowCodeBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/index/ShowCodeBackingBean.java new file mode 100644 index 0000000..8d4610b --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/index/ShowCodeBackingBean.java @@ -0,0 +1,114 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.index; + +import com.sun.jsftemplating.util.FileUtil; + +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.JavaHtmlConverter; + +import java.util.Map; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.io.Serializable; + +import javax.servlet.ServletContext; + +/** + * Backing bean for the show code page. + */ +public class ShowCodeBackingBean implements Serializable { + + // name of the file to display its content + private String fileName; + + // relative path to java and properties resources + private static final String RELATIVE_PATH = "com/sun/webui/jsf/example/"; + + /** Default constructor */ + public ShowCodeBackingBean() { + } + + /** + * Get file name. + */ + public String getFileName() { + // Get hyperlink parameter + Map map = FacesContext.getCurrentInstance().getExternalContext() + .getRequestParameterMap(); + String param = (String) map.get("param"); + this.fileName = (param != null) ? param : + MessageUtil.getMessage("index_noFileName"); + + return this.fileName; + } + + /** + * Get the source code in the form of html + * + */ + public String getSourceCode() { + try { + boolean isJavaCode = false; + String sourceName = this.fileName; + + if (sourceName.endsWith(".java")) { + sourceName = RELATIVE_PATH + sourceName; + isJavaCode = true; + } else if (sourceName.endsWith(".properties")) { + sourceName = RELATIVE_PATH + sourceName; + isJavaCode = false; + } else if (sourceName.endsWith(".jsp") + || sourceName.endsWith(".js") + || sourceName.endsWith(".jsf") + || sourceName.endsWith(".xml")) { + isJavaCode = false; + } else { + throw new Exception("Unknown file type"); + } + + // Get the source file input stream + InputStream is = FileUtil.searchForFile(sourceName, null).openStream(); + if (is == null) { + throw new Exception("Resource not found: " + sourceName); + } + + InputStreamReader reader = new InputStreamReader(is); + StringWriter writer = new StringWriter(); + + // It turns out that the Java->HTML converter does a decent + // job on the JSPs as well; we just want to tell it not to + // highlight keywords + JavaHtmlConverter.convert(reader, writer, true, isJavaCode); + + return writer.getBuffer().toString(); + } catch (Exception e) { + e.printStackTrace(); + return "Exception: " + e.toString(); + } + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/index/TableData.java b/samples/woodstock/src/com/sun/webui/jsf/example/index/TableData.java new file mode 100644 index 0000000..0cb68d1 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/index/TableData.java @@ -0,0 +1,231 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.index; + +import com.sun.webui.jsf.example.index.AppData; + +/** + * This class serves as a data wrapper for the Table component in the + * Example Application Index page. + */ +public class TableData { + + // Fill data for each example in an array object. + protected static final AppData[] data = { + new AppData("index_buttonName","index_buttonConcepts", "showButton", + new String[] { + "button/Button.jsf", + "button/ButtonResults.jsf", + "button/ButtonBackingBean.java"} + ), + new AppData("index_cbrbName","index_cbrbConcepts", "showCheckboxRadiobutton", + new String[] { + "cbrb/checkboxRadiobutton.jsf", + "cbrb/checkboxRadiobuttonResults.jsf", + "cbrb/CheckboxRadiobuttonBackingBean.java"} + ), + new AppData("index_labelName","index_labelConcepts", "showLabel", + new String[] { + "label/Label.jsf", + "label/LabelResults.jsf", + "label/Help.jsf", + "label/LabelBackingBean.java"} + ), + new AppData("index_alertName","index_alertConcepts", "showAlertIndex", + new String[] { + "alert/Alert.jsf", + "alert/InlineAlert.jsf", + "alert/PageAlertExample.jsf", + "alert/PageAlert.jsf", + "alert/HelpAlert.jsf", + "alert/InlineAlertBackingBean.java", + "alert/PageAlertBackingBean.java"} + ), + new AppData("index_textInputName", "index_textInputConcepts", "showTextInput", + new String[] { + "field/TextInput.jsf", + "field/TextInputResults.jsf", + "field/TextInputBackingBean.java"} + ), + new AppData("index_tableName", "index_tableConcepts", "showTableIndex", + new String[] { + "table/actions.jsf", + "table/actionsBottom.jsf", + "table/actionsTop.jsf", + "table/alarms.jsf", + "table/basicTable.jsf", + "table/customTitle.jsf", + "table/dynamicGroupTable.jsf", + "table/dynamicTable.jsf", + "table/embeddedActions.jsf", + "table/emptyCells.jsf", + "table/filter.jsf", + "table/filterPanel.jsf", + "table/groupTable.jsf", + "table/hiddenRowsActionsBottom.jsf", + "table/hiddenRowsActionsTop.jsf", + "table/hiddenSelectedRows.jsf", + "table/index.jsf", + "table/multipleHeadersFooters.jsf", + "table/liteTable.jsf", + "table/paginatedTable.jsf", + "table/preferences.jsf", + "table/preferencesPanel.jsf", + "table/selectMultipleRows.jsf", + "table/selectSingleRow.jsf", + "table/spacerColumn.jsf", + "table/sortableTable.jsf", + "table/table.jsf", + "table/TableBean.java", + "table/DynamicGroupTableBean.java", + "table/DynamicTableBean.java", + "table/util/Actions.java", + "table/util/Dynamic.java", + "table/util/Filter.java", + "table/util/Group.java", + "table/util/Messages.java", + "table/util/Name.java", + "table/util/Preferences.java", + "table/util/Select.java", + "table/js/actions.js", + "table/js/filter.js", + "table/js/preferences.js", + "table/js/select.js"} + ), + new AppData("index_addRemoveName", "index_addRemoveConcepts", "showAddRemove", + new String[] { + "addremove/AddRemove.jsf", + "addremove/AddRemoveResults.jsf", + "addremove/AddRemoveBackingBean.java", + "common/UserData.java"} + ), + new AppData("index_orderableListName", "index_orderableListConcepts", "showOrderableList", + new String[] { + "orderablelist/OrderableList.jsf", + "orderablelist/OrderableListResults.jsf", + "orderablelist/OrderableListBackingBean.java", + "orderablelist/Flavor.java", + "common/UserData.java"} + ), + new AppData("index_chooserUploader", "index_chooserUploaderConcepts", "showChooserUploader", + new String[] { + "chooseruploader/fileUploader.jsf", + "chooseruploader/fileChooser.jsf", + "chooseruploader/folderChooserPopup.jsf", + "chooseruploader/fileUploaderPopup.jsf", + "chooseruploader/folderChooser.jsf", + "chooseruploader/fileChooserPopup.jsf", + "chooseruploader/FileChooserBackingBean.java", + "chooseruploader/FolderChooserBackingBean.java", + "chooseruploader/FileUploaderBackingBean.java", + "chooseruploader/ChooserUploaderBackingBean.java", + "chooseruploader/ChooserUploaderValidator.java"} + ), + new AppData("index_menuListName", "index_menuListConcepts", "showMenuList", + new String[] { + "menu/MenuList.jsf", + "menu/MenuListResults.jsf", + "menu/MenuListBackingBean.java"} + ), + new AppData("index_mastheadName", "index_mastheadConcepts", "showMasthead", + new String[] { + "masthead/Index.jsf", + "masthead/Masthead.jsf", + "masthead/MastheadFacets.jsf", + "masthead/Version.jsf", + "masthead/Popup.jsf", + "masthead/Images.jsf", + "masthead/ResultMasthead.jsf", + "masthead/ResultMastheadFacets.jsf", + "masthead/MastheadBackingBean.java"} + ), + new AppData("index_propertysheet", "index_propertySheetConcepts", "showPropertySheet", + new String[] { + "propertysheet/PropertySheet.jsf", + "propertysheet/PropertySheetResult.jsf", + "propertysheet/PropertySheetBackingBean.java"} + ), + new AppData("index_editablelist", "index_editableListConcepts", "showEditableList", + new String[] { + "editablelist/editableList.jsf", + "editablelist/editableListResult.jsf", + "editablelist/EditableListBackingBean.java"} + ), + new AppData("index_pagetitleName", "index_pagetitleConcepts", "showPagetitle", + new String[] { + "pagetitle/Pagetitle.jsf", + "pagetitle/PagetitleBackingBean.java"} + ), + new AppData("index_hyperlink", "index_hyperlinkConcepts", "showHyperlink", + new String[] { + "hyperlink/hyperLink.jsf", + "hyperlink/hyperLinkResult.jsf", + "hyperlink/HyperlinkBackingBean.java"} + ), + new AppData("index_statictextName", "index_statictextConcepts", "showStaticText", + new String[] { + "statictext/Statictext.jsf", + "statictext/StatictextBackingBean.java", + "statictext/Employee.java", + "statictext/EmployeeConverter.java"} + ), + new AppData("index_commonTaskName", "index_commonTaskConcepts", "showCommonTask", + new String[] { + "commontask/commonTasks.jsf", + "commontask/sample.jsf", + "commontask/commonTaskBean.java"} + ), + new AppData("index_treeName", "index_treeConcepts", "showTreeIndex", + new String[] { + "tree/content.jsf", + "tree/dynamicTree.jsf", + "tree/header.jsf", + "tree/index.jsf", + "tree/navTree.jsf", + "tree/treeFrame.jsf", + "common/ClientSniffer.java", + "util/ExampleUtilities.java", + "tree/DynamicTreeBackingBean.java", + "tree/NavTreeBackingBean.java"} + ), + new AppData("index_progressBar", "index_progressBarConcepts", "showProgressBar", + new String[] { + "progressbar/index.jsf", + "progressbar/determinate.jsf", + "progressbar/indeterminate.jsf", + "progressbar/busy.jsf", + "progressbar/ProgressBarBackingBean.java"} + ), + new AppData("index_wizardName","index_wizardConcepts", "showWizardIndex", + new String[] { + "wizard/index.jsf", + "wizard/simpleWizard.jsf", + "wizard/SimpleWizardBackingBean.java"} + ) + }; + + /** Default constructor */ + public TableData() { + } +} + diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/label/LabelBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/label/LabelBackingBean.java new file mode 100644 index 0000000..5a8da58 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/label/LabelBackingBean.java @@ -0,0 +1,330 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ +/* + * LabelBackingBean.java + * + * Created on January 24, 2006, 1:09 PM + */ + +package com.sun.webui.jsf.example.label; + +import java.io.Serializable; + +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.validator.ValidatorException; +import javax.faces.application.FacesMessage; +import javax.faces.application.FacesMessage.Severity; +import javax.faces.event.ValueChangeEvent; +import javax.faces.event.ActionEvent; + +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.component.Checkbox; +import com.sun.webui.jsf.component.TextField; +import com.sun.webui.jsf.component.TextArea; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +/** + * Backing bean for the Label example. + */ +public class LabelBackingBean implements Serializable { + + private String address = ""; + private String phone = ""; + private boolean oliveSelected = false; + private boolean mushroomSelected = false; + private boolean pepperoniSelected = false; + private boolean sausageSelected = false; + private boolean anchovieSelected = false; + private boolean anchoviesAvailable = true; + + // By default, errors are rendered using an inline alert as per + // SWAED guidelines. But this limits you to a generic message + // when there are multiple errors on the page. Setting this to + // false shows all the messages listed in a messageGroup. + private static final boolean SHOW_ERRORS_IN_ALERT = true; + + /** Creates a new instance of LabelBackingBean */ + public LabelBackingBean() { + } + + /** Phone number validator. This will ONLY be called if a value was specified. */ + public void phoneValidator(FacesContext context, UIComponent component, Object value) { + // For simplicity's sake, we accept any positive integer < 1000 + try { + int n = Integer.parseInt(value.toString()); + if ((n <= 0) || (n >= 1000)) + throw new Exception(""); + } catch (Exception e) { + throw new ValidatorException( + new FacesMessage(MessageUtil.getMessage( + "label_invalidPhone"))); + } + } + + /** Address validator. This will ONLY be called if a value was specified */ + public void addressValidator(FacesContext context, UIComponent component, Object value) { + // For simplicity's sake, we accept any string but "XXX" as a valid address. + if (value.toString().equals("XXX")) { + throw new ValidatorException( + new FacesMessage(MessageUtil.getMessage( + "label_invalidAddress", "XXX"))); + } + } + + /** Olive topping validator */ + public void oliveValidator(FacesContext context, UIComponent component, Object value) { + } + + /** Mushroom topping validator */ + public void mushroomValidator(FacesContext context, UIComponent component, Object value) { + } + + /** Pepperoni topping validator */ + public void pepperoniValidator(FacesContext context, UIComponent component, Object value) { + } + + /** Sausage topping validator */ + public void sausageValidator(FacesContext context, UIComponent component, Object value) { + } + + /** Anchovie topping validator */ + public void anchovieValidator(FacesContext context, UIComponent component, Object value) { + if (!(value instanceof Boolean) || (value == Boolean.FALSE)) { + return; + } + + // OOPS! We are out of anchovies. + anchoviesAvailable = false; + throw new ValidatorException( + new FacesMessage(MessageUtil.getMessage("label_noAnchovies"))); + } + + /** Get the phone number property */ + public String getPhone() { + return phone; + } + + /** Set the phone number property */ + public void setPhone(String phone) { + this.phone = phone; + } + + /** Get the address property */ + public String getAddress() { + return address; + } + + /** Set the address property */ + public void setAddress(String address) { + this.address = address; + } + + /** Get the olive topping selection */ + public boolean getOliveSelected() { + return oliveSelected; + } + + /** Set the olive topping selection */ + public void setOliveSelected(boolean b) { + oliveSelected = b; + } + + /** Get the mushroom topping selection */ + public boolean getMushroomSelected() { + return mushroomSelected; + } + + /** Set the mushroom topping selection */ + public void setMushroomSelected(boolean b) { + mushroomSelected = b; + } + + /** Get the pepperoni topping selection */ + public boolean getPepperoniSelected() { + return pepperoniSelected; + } + + /** Set the pepperoni topping selection */ + public void setPepperoniSelected(boolean b) { + pepperoniSelected = b; + } + + /** Get the sausage topping selection */ + public boolean getSausageSelected() { + return sausageSelected; + } + + /** Set the sausage topping selection */ + public void setSausageSelected(boolean b) { + sausageSelected = b; + } + + /** Get the anchovie topping selection */ + public boolean getAnchovieSelected() { + return anchovieSelected; + } + + /** Set the anchovie topping selection */ + public void setAnchovieSelected(boolean b) { + anchovieSelected = b; + } + + /** Get the label for the anchovie selection */ + public String getAnchovieLabel() { + if (anchoviesAvailable) { + return MessageUtil.getMessage("label_anchovies"); + } else { + return MessageUtil.getMessage("label_noAnchovies"); + } + } + + /** Action handler for the Place Order button. */ + public String placeOrder() { + return "showLabelResults"; + } + + /** ActionListener for the Reset button */ + public void resetActionListener(ActionEvent e) { + // Since the action is immediate, the components won't + // go through the Update Model phase. However, its submitted value + // gets set in the Apply Request Value phase and this value is retained + // when the page is redisplayed. + // + // So, we need to explicitly erase the submitted values and then update + // the model object with initial values. + Checkbox cb; + FacesContext context = FacesContext.getCurrentInstance(); + cb = (Checkbox) context.getViewRoot().findComponent("form1:oliveTopping"); + cb.setSubmittedValue(null); + cb.setValue(null); + cb = (Checkbox) context.getViewRoot().findComponent("form1:mushroomTopping"); + cb.setSubmittedValue(null); + cb.setValue(null); + cb = (Checkbox) context.getViewRoot().findComponent("form1:pepperoniTopping"); + cb.setSubmittedValue(null); + cb.setValue(null); + cb = (Checkbox) context.getViewRoot().findComponent("form1:sausageTopping"); + cb.setSubmittedValue(null); + cb.setValue(null); + cb = (Checkbox) context.getViewRoot().findComponent("form1:anchovieTopping"); + cb.setSubmittedValue(null); + cb.setValue(null); + + TextField tf = (TextField) context.getViewRoot().findComponent("form1:phoneNum"); + tf.setSubmittedValue(""); + TextArea ta = (TextArea) context.getViewRoot().findComponent("form1:address"); + ta.setSubmittedValue(""); + + reset(); + } + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + /** Action handler when navigating back to the Label example from results page. */ + public String showLabel() { + reset(); + return "showLabel"; + } + + + // Reset model properties for next order. + private void reset() { + setAddress(""); + setPhone(""); + setOliveSelected(false); + setMushroomSelected(false); + setPepperoniSelected(false); + setSausageSelected(false); + setAnchovieSelected(false); + + // Assume we just got a delivery! + anchoviesAvailable = true; + } + + /** Render the message group is there is any error on the page */ + public boolean getMessageGroupRendered() { + // Never render if showing error in an inline alert. + if (SHOW_ERRORS_IN_ALERT) + return false; + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) == 0) { + return true; + } + return false; + } + + /** Render the alert is there is any error on the page */ + public boolean getAlertRendered() { + // Never render if showing errors in a message group. + if (!SHOW_ERRORS_IN_ALERT) + return false; + + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) == 0) { + return true; + } + return false; + } + + /** Return summary of pizza order */ + public String getPizza() { + String result = ""; + if (!getOliveSelected() && !getMushroomSelected() && !getPepperoniSelected() + && !getSausageSelected()) + result = MessageUtil.getMessage("label_plainPizza"); + else { + result = MessageUtil.getMessage("label_toppingsPizza"); + if (getOliveSelected()) + result += " " + MessageUtil.getMessage("label_oliveResult"); + if (getMushroomSelected()) + result += " " + MessageUtil.getMessage("label_mushroomResult"); + if (getPepperoniSelected()) + result += " " + MessageUtil.getMessage("label_pepperoniResult"); + if (getSausageSelected()) + result += " " + MessageUtil.getMessage("label_sausageResult"); + } + return result; + } + + /** Return summary of delivery location */ + public String getWhere() { + String args[] = new String[2]; + args[0] = getAddress(); + args[1] = getPhone(); + return MessageUtil.getMessage("label_whereResult", args); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/masthead/MastheadBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/masthead/MastheadBackingBean.java new file mode 100644 index 0000000..66c5501 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/masthead/MastheadBackingBean.java @@ -0,0 +1,373 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.masthead; + +import com.sun.webui.jsf.component.Hyperlink; +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; +import java.io.Serializable; +import javax.faces.event.ValueChangeEvent; + +import com.sun.webui.jsf.example.common.MessageUtil; + +/** + * Backing bean for Image and Masthead example. + */ + +public class MastheadBackingBean implements Serializable { + + // Holds the server and user names. + private String server = "test_server"; + private String user = "test_user"; + + // Holds the text to be displayed in the alert boxes. + private String message = null; + private String detail = null; + + // Holds the severity of Alarms clicked. + private String severity = null; + + // The outcome strings used in the faces config file + private static final String MASTHEAD_INDEX = "showMasthead"; + private static final String MASTHEAD1 = "showMasthead1"; + private static final String MASTHEAD2 = "showMasthead2"; + private static final String MASTHEAD3 = "showMasthead3"; + private static final String RESULT_MASTHEAD = "showResultMasthead"; + private static final String RESULT_MASTHEAD_FACETS = "showResultMastheadFacets"; + + // Initial value for renedering the alert boxes. + private boolean isRendered1 = false; + private boolean isRendered2 = false; + private boolean isRendered3 = false; + private boolean isRendered4 = false; + + // Value for renedering the Back button. + private boolean buttonDisplayed = false; + + // Default selection value for the "status area facet" checkbox. + private boolean cb1Selected = true; + private boolean cb2Selected = true; + private boolean cb3Selected = true; + private boolean cb4Selected = true; + + // Holds the Utility Links. + private Hyperlink[] links = new Hyperlink[2]; + + // Holds the Alarms. + private int[] alarms = new int[] {1, 2, 3, 4}; + + /** Creates a new instance of MastheadBackingBean. */ + public MastheadBackingBean() { + + links[0] = new Hyperlink(); + links[0].setText(MessageUtil.getMessage("masthead_utilityLink1Text")); + links[0].setUrl("http://www.sun.com"); + links[0].setToolTip + (MessageUtil.getMessage("masthead_utilityLink1ToolTip")); + links[0].setTarget("_blank"); + + links[1] = new Hyperlink(); + links[1].setText(MessageUtil.getMessage("masthead_utilityLink2Text")); + links[1].setUrl("http://developers.sun.com/"); + links[1].setToolTip + (MessageUtil.getMessage("masthead_utilityLink2ToolTip")); + } + + /** Returns the server name. */ + public String getServer() { + return server; + } + + /** Returns the user name. */ + public String getUser() { + return user; + } + + /** Returns message to be displayed in alert box. */ + public String getMessage() { + return message; + } + + /** Returns detail to be displayed in alert box. */ + public String getDetail() { + return detail; + } + + /** + * Returns value that decides whether the alertbox should be rendered or + * not in Masthead with Attributes Page. + */ + public boolean getIsRendered1() { + return isRendered1; + } + + /** + * Returns value that decides whether the alertbox should be rendered or + * not in Masthead with Facets Page. + */ + public boolean getIsRendered2() { + return isRendered2; + } + + /** + * Return value that decides whether the alertbox should be rendered or + * not in Results Page of Masthead with Attributes. + */ + public boolean getisRendered3() { + return isRendered3; + } + + /** + * Returns value that decides whether the alertbox should be rendered or + * not in Results Page of Masthead with Facets. + */ + public boolean getisRendered4() { + return isRendered4; + } + + /** + * Returns value that decides whether the Back button should be rendered or + * not in Results Page of Masthead with Facets. + */ + public boolean getbuttonDisplayed() { + return buttonDisplayed; + } + + /** Returns Utility Links. */ + public Hyperlink[] getLinks() { + return links; + } + + /** Set alarms in the masthead. */ + public void setAlarms(int[] alarms) { + this.alarms = alarms; + } + + /** Returns the alarms. */ + public int[] getAlarms() { + return alarms; + } + + /** Returns the enable/disable state of the status area facet checkbox. */ + public boolean getCb1Selected() { + return cb1Selected; + } + + /** Sets the enable/disable state of the status area facet checkbox. */ + public void setCb1Selected(boolean b) { + cb1Selected = b; + } + + /** Returns the enable/disable state of the status area facet checkbox. */ + public boolean getCb2Selected() { + return cb2Selected; + } + + /** Sets the enable/disable state of the status area facet checkbox. */ + public void setCb2Selected(boolean b) { + cb2Selected = b; + } + + /** Returns the enable/disable state of the status area facet checkbox. */ + public boolean getCb3Selected() { + return cb3Selected; + } + + /** Sets the enable/disable state of the status area facet checkbox. */ + public void setCb3Selected(boolean b) { + cb3Selected = b; + } + + /** Returns the enable/disable state of the status area facet checkbox. */ + public boolean getCb4Selected() { + return cb4Selected; + } + + /** Sets the enable/disable state of the status area facet checkbox. */ + public void setCb4Selected(boolean b) { + cb4Selected = b; + } + + /** Removes displayed alert box when Update Masthead is clicked. */ + public void buttonClicked() { + isRendered2 = false; + return; + } + + /** Message to be displayed when HelpLink is clicked. */ + public void helpPage1Clicked() { + isRendered1 = true; + message = MessageUtil.getMessage("masthead_helpLinkClicked"); + return; + } + + /** Message to be displayed when LogoutLink is clicked. */ + public String logoutPage1Clicked() { + isRendered1 = false; + isRendered3 = true; + message = MessageUtil.getMessage("masthead_logoutLinkClicked"); + return new String(RESULT_MASTHEAD); + } + + /** Message to be displayed when VersionLink is clicked. */ + public void versionPage1Clicked() { + isRendered1 = true; + message = MessageUtil.getMessage("masthead_versionLinkClicked"); + return; + } + + /** Message to be displayed when ConsoleLink is clicked. */ + public void consolePage1Clicked() { + isRendered1 = true; + message = MessageUtil.getMessage("masthead_consoleLinkClicked"); + return; + } + + /** Message to be displayed when HelpLink is clicked. */ + public void helpPage2Clicked() { + isRendered2 = true; + message = MessageUtil.getMessage("masthead_helpLinkClicked"); + detail = ""; + return; + } + + /** Message to be displayed when LogoutLink is clicked. */ + public String logoutPage2Clicked() { + isRendered2 = false; + isRendered4 = true; + buttonDisplayed = false; + message = MessageUtil.getMessage("masthead_logoutLinkClicked"); + detail = ""; + return new String(RESULT_MASTHEAD_FACETS); + } + + /** Message to be displayed when VersionLink is clicked. */ + public void versionPage2Clicked() { + isRendered2 = true; + message = MessageUtil.getMessage("masthead_versionLinkClicked"); + detail = ""; + return; + } + + /** Message to be displayed when ConsoleLink is clicked. */ + public void consolePage2Clicked() { + isRendered2 = true; + message = MessageUtil.getMessage("masthead_consoleLinkClicked"); + detail = ""; + return; + } + + /** Message to be displayed when Notification Phrase is clicked. */ + public String notificationClicked() { + isRendered2 = false; + isRendered4 = true; + buttonDisplayed = true; + message = MessageUtil.getMessage("masthead_notificationClicked"); + detail = ""; + return new String(RESULT_MASTHEAD_FACETS); + } + + /** Message to be displayed when Job Status is clicked. */ + public String jobstatusClicked() { + isRendered2 = false; + isRendered4 = true; + buttonDisplayed = true; + message = MessageUtil.getMessage("masthead_jobStatusClicked"); + detail = ""; + return new String(RESULT_MASTHEAD_FACETS); + } + + /** Message to be displayed when Alarms are clicked. */ + public String alarmClicked() { + isRendered2 = false; + isRendered4 = true; + buttonDisplayed = true; + message = MessageUtil.getMessage("masthead_alarmClicked"); + + severity = (String) FacesContext.getCurrentInstance(). + getExternalContext().getRequestParameterMap(). + get("severity"); + + if (severity.equals("critical")) + { + detail = MessageUtil.getMessage("masthead_criticalalarmClicked"); + } else if (severity.equals("major")) + { + detail = MessageUtil.getMessage("masthead_majoralarmClicked"); + } else if (severity.equals("minor")) + { + detail = MessageUtil.getMessage("masthead_minoralarmClicked"); + } + return new String(RESULT_MASTHEAD_FACETS); + } + + /** Page Navigation for breadcrumb. */ + public String goToMastheadIndex() { + return new String(MASTHEAD_INDEX); + } + + /** Page Navigation for Masthead with Atributes Page. */ + public String goToPage1() { + isRendered1 = false; + isRendered2 = false; + return new String(MASTHEAD1); + } + + /** Page Navigation for Masthead with Facets Page. */ + public String goToPage2() { + isRendered1 = false; + isRendered2 = false; + return new String(MASTHEAD2); + } + + /** Page Navigation for Images and imageHyperlink Page. */ + public String goToPage3() { + isRendered1 = false; + isRendered2 = false; + return new String(MASTHEAD3); + } + + /** ValueChangelistener for checkbox that shows Notification Info. */ + public void listener1 (ValueChangeEvent event) { + cb1Selected = ((Boolean) event.getNewValue()).booleanValue(); + return; + } + + /** ValueChangelistener for checkbox that shows Jobs Running Info. */ + public void listener2 (ValueChangeEvent event) { + cb2Selected = ((Boolean) event.getNewValue()).booleanValue(); + return; + } + + /** ValueChangelistener for checkbox that shows Time Stamp Info. */ + public void listener3 (ValueChangeEvent event) { + cb3Selected = ((Boolean) event.getNewValue()).booleanValue(); + return; + } + + /** ValueChangelistener for checkbox that shows Current Alarms Info. */ + public void listener4 (ValueChangeEvent event) { + cb4Selected = ((Boolean) event.getNewValue()).booleanValue(); + return; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/menu/MenuListBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/menu/MenuListBackingBean.java new file mode 100644 index 0000000..ffacb87 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/menu/MenuListBackingBean.java @@ -0,0 +1,459 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.menu; + +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; + +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.model.OptionGroup; +import com.sun.webui.jsf.model.OptionTitle; + +import com.sun.webui.jsf.component.DropDown; +import com.sun.webui.jsf.component.Listbox; + +import com.sun.webui.jsf.example.index.IndexBackingBean; +import com.sun.webui.jsf.example.common.MessageUtil; + +import java.io.Serializable; + +/** + * Backing bean for Menu and List example. + * + * Note that we must implement java.io.Serializable or + * javax.faces.component.StateHolder in case client-side + * state saving is used, or if server-side state saving is + * used with a distributed system. + */ +public class MenuListBackingBean implements Serializable { + + /** Holds value of property testCaseOptions. */ + private Option[] testCaseOptions = null; + + /** Holds value of property jumpMenuOptions. */ + private Option[] jumpMenuOptions = null; + + /** Holds value of property jumpMenuSelectedOption. */ + private String jumpMenuSelectedOption = null; + + /** Holds value of property standardMenuOptions. */ + private Option[] standardMenuOptions = null; + + /** Holds value of property standardMenuSelectedOption. */ + private String standardMenuSelectedOption = null; + + /** Holds value of property listboxOptions. */ + private Option[] listboxOptions = null; + + /** Holds value of property listboxSelectedOption. */ + private String listboxSelectedOption = null; + + /** Holds value of property jumpMenuDisbaled. */ + private boolean jumpMenuDisabled = false; + + /** Holds value of property standardMenuDisbaled. */ + private boolean standardMenuDisabled = false; + + /** Holds value of property listboxDisbaled. */ + private boolean listboxDisabled = false; + + /** Holds value of property alertDetail. */ + private String alertDetail = null; + + /** Holds value of property alertRendered. */ + private boolean alertRendered = false; + + /** Flag indicationg the disabled state of the menus and list. */ + private boolean menusDisabled = false; + + /** Outcome strings used in the faces config file. */ + private static final String SHOW_MENULIST_RESULTS = "showMenuListResults"; + + /** Default constructor. */ + public MenuListBackingBean() { + // Test case menu options. + testCaseOptions = new Option[5]; + testCaseOptions[0] = new OptionTitle( + MessageUtil.getMessage("menu_testCase0")); + testCaseOptions[1] = new Option("menu_testCase1", + MessageUtil.getMessage("menu_testCase1")); + testCaseOptions[2] = new Option("menu_testCase2", + MessageUtil.getMessage("menu_testCase2")); + testCaseOptions[3] = new Option("menu_testCase3", + MessageUtil.getMessage("menu_testCase3")); + testCaseOptions[4] = new Option("menu_testCase4", + MessageUtil.getMessage("menu_testCase4")); + + // Jump menu option group 1. + Option[] groupedOptions1 = new Option[3]; + groupedOptions1[0] = new Option("action_A_value", + MessageUtil.getMessage("menu_actiona")); + groupedOptions1[1] = new Option("action_B_value", + MessageUtil.getMessage("menu_actionb")); + groupedOptions1[2] = new Option("action_C_value", + MessageUtil.getMessage("menu_actionc")); + + OptionGroup jumpGroup1 = new OptionGroup(); + jumpGroup1.setLabel(MessageUtil.getMessage("menu_actionGroup1")); + jumpGroup1.setOptions(groupedOptions1); + + // Jump menu option group 2. + Option[] groupedOptions2 = new Option[3]; + groupedOptions2[0] = new Option("action_D_value", + MessageUtil.getMessage("menu_actiond")); + groupedOptions2[1] = new Option("action_E_value", + MessageUtil.getMessage("menu_actione")); + groupedOptions2[2] = new Option("action_F_value", + MessageUtil.getMessage("menu_actionf")); + + OptionGroup jumpGroup2 = new OptionGroup(); + jumpGroup2.setLabel(MessageUtil.getMessage("menu_actionGroup2")); + jumpGroup2.setOptions(groupedOptions2); + + // Jump menu options. + jumpMenuOptions = new Option[9]; + jumpMenuOptions[0] = new OptionTitle( + MessageUtil.getMessage("menu_action0")); + jumpMenuOptions[1] = new Option("action_1_value", + MessageUtil.getMessage("menu_action1")); + jumpMenuOptions[2] = new Option("action_2_value", + MessageUtil.getMessage("menu_action2")); + jumpMenuOptions[3] = new Option("action_3_value", + MessageUtil.getMessage("menu_action3")); + jumpMenuOptions[4] = jumpGroup1; + jumpMenuOptions[5] = jumpGroup2; + jumpMenuOptions[6] = new Option("action_4_value", + MessageUtil.getMessage("menu_action4")); + jumpMenuOptions[7] = new Option("action_5_value", + MessageUtil.getMessage("menu_action5")); + jumpMenuOptions[8] = new Option("action_6_value", + MessageUtil.getMessage("menu_action6")); + + // Standard menu and list option group 1. + Option[] listGroupedOptions1 = new Option[3]; + listGroupedOptions1[0] = new Option("option_A_value", + MessageUtil.getMessage("menu_optiona")); + listGroupedOptions1[1] = new Option("option_B_value", + MessageUtil.getMessage("menu_optionb")); + listGroupedOptions1[2] = new Option("option_C_value", + MessageUtil.getMessage("menu_optionc")); + + OptionGroup standardGroup1 = new OptionGroup(); + standardGroup1.setLabel(MessageUtil.getMessage("menu_optionGroup1")); + standardGroup1.setOptions(listGroupedOptions1); + + // Standard menu and list option group 2. + Option[] listGroupedOptions2 = new Option[3]; + listGroupedOptions2[0] = new Option("option_D_value", + MessageUtil.getMessage("menu_optiond")); + listGroupedOptions2[1] = new Option("option_E_value", + MessageUtil.getMessage("menu_optione")); + listGroupedOptions2[2] = new Option("option_F_value", + MessageUtil.getMessage("menu_optionf")); + + OptionGroup standardGroup2 = new OptionGroup(); + standardGroup2.setLabel(MessageUtil.getMessage("menu_optionGroup2")); + standardGroup2.setOptions(listGroupedOptions2); + + // Standard menu and scrolling list options. + Option[] options = new Option[9]; + options[0] = new Option("option_0_value", + MessageUtil.getMessage("menu_option0")); + options[1] = new Option("option_1_value", + MessageUtil.getMessage("menu_option1")); + options[2] = new Option("option_2_value", + MessageUtil.getMessage("menu_option2")); + options[3] = new Option("option_3_value", + MessageUtil.getMessage("menu_option3")); + options[4] = standardGroup1; + options[5] = standardGroup2; + options[6] = new Option("option_4_value", + MessageUtil.getMessage("menu_option4")); + options[7] = new Option("option_5_value", + MessageUtil.getMessage("menu_option5")); + options[8] = new Option("option_6_value", + MessageUtil.getMessage("menu_option6")); + + standardMenuOptions = options; + listboxOptions = options; + + // Set the initial selection for standard menu and scrolling list. + standardMenuSelectedOption = (String) standardMenuOptions[0].getValue(); + listboxSelectedOption = (String) listboxOptions[0].getValue(); + } + + /** Return the array of test case options */ + public Option[] getTestCaseOptions() { + return testCaseOptions; + } + + /** Return the array of jump menu options */ + public Option[] getJumpMenuOptions() { + return this.jumpMenuOptions; + } + + /** Set the array of jump menu options */ + public void setJumpMenuOptions(Option[] jumpMenuOptions) { + this.jumpMenuOptions = jumpMenuOptions; + } + + /** Get the value of property jumpMenuSelectedOption */ + public String getJumpMenuSelectedOption() { + return this.jumpMenuSelectedOption; + } + + /** Set the value of property jumpMenuSelectedOption */ + public void setJumpMenuSelectedOption(String jumpMenuSelectedOption) { + this.jumpMenuSelectedOption = jumpMenuSelectedOption; + } + + /** Return the array of standard menu options */ + public Option[] getStandardMenuOptions() { + return this.standardMenuOptions; + } + + /** Set the array of standard menu options */ + public void setStandardMenuOptions(Option[] standardMenuOptions) { + this.standardMenuOptions = standardMenuOptions; + } + + /** Get the value of property standardMenuSelectedOption */ + public String getStandardMenuSelectedOption() { + return this.standardMenuSelectedOption; + } + + /** Set the value of property standardMenuSelectedOption */ + public void setStandardMenuSelectedOption(String standardMenuSelectedOption) { + this.standardMenuSelectedOption = standardMenuSelectedOption; + } + + /** Return the array of listbox options */ + public Option[] getListboxOptions() { + return this.listboxOptions; + } + + /** Get the value of property listboxSelectedOption */ + public String getListboxSelectedOption() { + return this.listboxSelectedOption; + } + + /** Set the value of property listboxSelectedOption */ + public void setListboxSelectedOption(String listboxSelectedOption) { + this.listboxSelectedOption = listboxSelectedOption; + } + + /** Get the disabled state of the jump menu. */ + public boolean getJumpMenuDisabled() { + return jumpMenuDisabled; + } + + /** Set the disabled state of the jump menu. */ + public void setJumpMenuDisabled(boolean jumpMenuDisabled) { + this.jumpMenuDisabled = jumpMenuDisabled; + } + + /** Get the disabled state of the standard menu. */ + public boolean getStandardMenuDisabled() { + return standardMenuDisabled; + } + + /** Set the disabled state of the standard menu. */ + public void setStandardMenuDisabled(boolean standardMenuDisabled) { + this.standardMenuDisabled = standardMenuDisabled; + } + + /** Get the disabled state of the scroll list. */ + public boolean getListboxDisabled() { + return listboxDisabled; + } + + /** Set the disabled state of the scroll list. */ + public void setListboxDisabled(boolean listboxDisabled) { + this.listboxDisabled = listboxDisabled; + } + + /** Get the value of property alertDetail. */ + public String getAlertDetail() { + return alertDetail; + } + + /** Get the value of property alertRendered. */ + public boolean getAlertRendered() { + return alertRendered; + } + + /** Return the result for standard menu. */ + public String getStandardMenuResult() { + String noOption = (String) standardMenuOptions[0].getValue(); + if (standardMenuSelectedOption.equals(noOption)) { + return MessageUtil.getMessage("menu_noOption"); + } + return standardMenuSelectedOption; + } + + /** Return the result for scrolling list. */ + public String getScrollingListResult() { + String noOption = (String) listboxOptions[0].getValue(); + if (listboxSelectedOption.equals(noOption)) { + return MessageUtil.getMessage("menu_noOption"); + } + return listboxSelectedOption; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Listeners + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action listener for the jump dropdown menu. */ + public void processJumpMenuSelection(ActionEvent e) { + FacesContext context = FacesContext.getCurrentInstance(); + String clientID = e.getComponent().getClientId(context); + + DropDown dropDown = (DropDown) e.getComponent(); + String selected = (String) dropDown.getSelected(); + + // We only want the last part of the fully-qualified clientID + int n = clientID.lastIndexOf(':'); + if (n >= 0) { + clientID = clientID.substring(n + 1); + } + + Object[] args = new Object[2]; + args[0] = clientID; + args[1] = selected; + alertDetail = MessageUtil.getMessage("menu_alertElementDetail", args); + alertRendered = true; + } + + /** Action listener for the test case dropdown menu. */ + public void processTestCaseMenuSelection(ActionEvent e) { + // disable alert. + alertRendered = false; + + + // Since the action is immediate, the components won't go through the + // Update Model phase. So, we need to explicitly set the values and + // update the model object for the given action selected. + FacesContext context = FacesContext.getCurrentInstance(); + DropDown dropDown = (DropDown) e.getComponent(); + String selected = (String) dropDown.getSelected(); + Listbox listbox; + DropDown dd; + + if (selected.equals("menu_testCase1")) { + listbox = (Listbox) context.getViewRoot().findComponent( + "form:scrollList"); + listbox.setSubmittedValue(null); + + dd = (DropDown) context.getViewRoot().findComponent( + "form:standardMenu"); + dd.setSubmittedValue(null); + + // set the selected option to the default option. + listboxSelectedOption = (String) listboxOptions[0].getValue(); + standardMenuSelectedOption = + (String) standardMenuOptions[0].getValue(); + + disable(true); + menusDisabled = true; + + } else if (selected.equals("menu_testCase2")) { + // Need to enable the menus and list before disabling their options. + if (menusDisabled) { + disable(false); + } + disableOptions(true); + + } else if (selected.equals("menu_testCase3")) { + listbox = (Listbox) context.getViewRoot().findComponent( + "form:scrollList"); + listbox.setSubmittedValue(null); + + dd = (DropDown) context.getViewRoot().findComponent( + "form:standardMenu"); + dd.setSubmittedValue(null); + + disable(false); + + } else if (selected.equals("menu_testCase4")) { + disableOptions(false); + } + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Handlers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + // reset. + alertRendered = false; + menusDisabled = false; + jumpMenuSelectedOption = null; + standardMenuSelectedOption = (String) standardMenuOptions[0].getValue(); + listboxSelectedOption = (String) listboxOptions[0].getValue(); + disable(false); + disableOptions(false); + + return IndexBackingBean.INDEX_ACTION; + } + + /** Action handler when navigating to the results page. */ + public String showMenuListResults() { + alertRendered = false; + return SHOW_MENULIST_RESULTS; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private Methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Helper method to set the disabled state of the menus and list. */ + private void disable(boolean value) { + setJumpMenuDisabled(value); + setStandardMenuDisabled(value); + setListboxDisabled(value); + } + + /** Helper method to set the disabled state of the menus and list options. */ + private void disableOptions(boolean value) { + disableOptions(jumpMenuOptions, value); + disableOptions(standardMenuOptions, value); + disableOptions(listboxOptions, value); + } + + /** Helper method to set the disabled state of the menus and list options. */ + private void disableOptions(Option[] options, boolean value) { + for (int i = 1; i < options.length; i++) { + if (options[i] instanceof OptionGroup) { + Option[] groupedOptions = + ((OptionGroup)options[i]).getOptions(); + for (int j = 0; j < groupedOptions.length; j++) { + groupedOptions[j].setDisabled(value); + } + } else { + options[i].setDisabled(value); + } + } + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/orderablelist/Flavor.java b/samples/woodstock/src/com/sun/webui/jsf/example/orderablelist/Flavor.java new file mode 100644 index 0000000..e906d2b --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/orderablelist/Flavor.java @@ -0,0 +1,56 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.orderablelist; + +/** + * This class represents a flavor. + */ +public class Flavor { + + /** Name of a flavor. */ + private String name; + + /** Creates a new instance of Flavor. */ + public Flavor() { + } + + /** Creates a new instance of Flavor. */ + public Flavor(String name) { + this.name = name; + } + + /** Get the name of the flavor. */ + public String getName() { + return this.name; + } + + /** Set the name of the flavor. */ + public void setName(String name) { + this.name = name; + } + + /** Returns a string representation of the object. */ + public String toString() { + return name; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/orderablelist/OrderableListBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/orderablelist/OrderableListBackingBean.java new file mode 100644 index 0000000..9eef23a --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/orderablelist/OrderableListBackingBean.java @@ -0,0 +1,133 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.orderablelist; + +import javax.faces.event.ActionEvent; +import javax.faces.context.FacesContext; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.common.UserData; + +import com.sun.webui.jsf.component.OrderableList; + +import java.io.Serializable; + +/** + * Backing bean for Orderable List example. + */ +public class OrderableListBackingBean implements Serializable { + + /** Holds value of property listItems. */ + private String[] listItems = null; + + /** The original list. */ + private String[] originalList = null; + + /** UserData. */ + private UserData userData = null; + + /** Default constructor. */ + public OrderableListBackingBean() { + // List items. + listItems = new String[17]; + listItems[0] = MessageUtil.getMessage("orderablelist_flavor1"); + listItems[1] = MessageUtil.getMessage("orderablelist_flavor2"); + listItems[2] = MessageUtil.getMessage("orderablelist_flavor3"); + listItems[3] = MessageUtil.getMessage("orderablelist_flavor4"); + listItems[4] = MessageUtil.getMessage("orderablelist_flavor5"); + listItems[5] = MessageUtil.getMessage("orderablelist_flavor6"); + listItems[6] = MessageUtil.getMessage("orderablelist_flavor7"); + listItems[7] = MessageUtil.getMessage("orderablelist_flavor8"); + listItems[8] = MessageUtil.getMessage("orderablelist_flavor9"); + listItems[9] = MessageUtil.getMessage("orderablelist_flavor10"); + listItems[10] = MessageUtil.getMessage("orderablelist_flavor11"); + listItems[11] = MessageUtil.getMessage("orderablelist_flavor12"); + listItems[12] = MessageUtil.getMessage("orderablelist_flavor13"); + listItems[13] = MessageUtil.getMessage("orderablelist_flavor14"); + listItems[14] = MessageUtil.getMessage("orderablelist_flavor15"); + listItems[15] = MessageUtil.getMessage("orderablelist_flavor16"); + listItems[16] = MessageUtil.getMessage("orderablelist_flavor17"); + + originalList = listItems; + } + + /** Get the value of property listItems. */ + public String[] getListItems() { + return this.listItems; + } + + /** Set the value of property listItems. */ + public void setListItems(String[] listItems) { + this.listItems = listItems; + } + + /** Get UserData created with an array containing user's ordered list. */ + public UserData getUserData() { + if (userData == null) { + Flavor[] flavor = new Flavor[listItems.length]; + for (int i = 0; i < listItems.length; i++) { + flavor[i] = new Flavor(listItems[i]); + } + + userData = new UserData(flavor); + } + return userData; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Listeners + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action listener for the reset button. */ + public void resetOrder(ActionEvent e) { + // Sine the action is immediate, the orderable list component won't + // go through the Update Model phase. However, its submitted value + // gets set in the Apply Request Value phase and this value is retained + // when the page is redisplayed. + // + // So, we need to explicitly erase the submitted value and then update + // the model object with the original list. + FacesContext context = FacesContext.getCurrentInstance(); + OrderableList list = + (OrderableList) context.getViewRoot().findComponent( + "form:contentPageTitle:orderableList"); + list.setSubmittedValue(null); + + // Set the model object. + listItems = originalList; + } + + /** Action listener for the breadcrumbs link. */ + public void processLinkAction(ActionEvent e) { + // All apps should revert to their initial state + // when they are re-visitted from the Example index. + // So, set the model object to the original list. + listItems = originalList; + } + + /** Action listener for the ShowItems button. */ + public void resetDataProvider(ActionEvent e) { + // reset data provider; + userData = null; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/pagetitle/PagetitleBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/pagetitle/PagetitleBackingBean.java new file mode 100644 index 0000000..daca284 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/pagetitle/PagetitleBackingBean.java @@ -0,0 +1,179 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.pagetitle; + +import java.beans.*; +import java.io.Serializable; +import com.sun.webui.jsf.component.DropDown; +import com.sun.webui.jsf.component.TextField; +import com.sun.webui.jsf.model.Option; +import javax.faces.component.UIComponent; +import javax.faces.event.ActionEvent; +import javax.faces.event.AbortProcessingException; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.application.FacesMessage; + +import com.sun.webui.jsf.example.common.MessageUtil; + +/** + * Backing bean for Content Page Title example. + */ + +public class PagetitleBackingBean implements Serializable { + + // Holds the text to be displayed in the alert boxes. + private String message = null; + private String detail = null; + + // Holds the texts to be displayed in the text fields. + private String text1 = null; + private String text2 = null; + + // Holds the PageViews + private Option[] views = null; + + // Holds the selected item of PageView + private String selectedItem = "View1"; + + // Initial value for renedering the Alert box. + private boolean isRendered = false; + + /** Creates a new instance of PagetitleBackingBean. */ + public PagetitleBackingBean() { + views = new Option[3]; + views[0] = new Option("View1", MessageUtil.getMessage("pagetitle_view1")); + views[1] = new Option("View2", MessageUtil.getMessage("pagetitle_view2")); + views[2] = new Option("View3", MessageUtil.getMessage("pagetitle_view3")); + } + + /** + * Returns value that decides whether the alertbox should be rendered or + * not. + */ + public boolean getIsRendered() { + return isRendered; + } + + /** Return message to be displayed in alert box. */ + public String getMessage() { + return message; + } + + /** Returns detail to be displayed in alert box. */ + public String getDetail() { + return detail; + } + + /** Returns options to be displayed in PageView dropdown menu. */ + public Option[] getViews() { + isRendered = false; + return views; + } + + /** Return text to be displayed in textfield. */ + public String getText1() { + return text1; + } + + /** Sets text to be displayed in textfield. */ + public void setText1(String text1) { + this.text1 = text1; + } + + /** Return text to be displayed in textfield. */ + public String getText2() { + return text2; + } + + /** Sets text to be displayed in textfield. */ + public void setText2(String text2) { + this.text2 = text2; + } + + /** Returns the selected item in the PageView. */ + public String getSelectedItem() { + return selectedItem; + } + + /** Sets the selected item in the PageView. */ + public void setSelectedItem(String s) { + selectedItem = s; + } + + /** Checks if there is any error on the page. */ + public boolean isErrorsOnPage() { + message = MessageUtil.getMessage("pagetitle_error"); + detail = MessageUtil.getMessage("pagetitle_detail"); + FacesMessage.Severity severity = + FacesContext.getCurrentInstance().getMaximumSeverity(); + if (severity == null) { + return false; + } + if (severity.compareTo(FacesMessage.SEVERITY_ERROR) >= 0) { + return true; + } + return false; + } + + /** Message to be displayed when Save Button is clicked. */ + public void saveClicked() { + isRendered = true; + message = MessageUtil.getMessage("pagetitle_elementClicked"); + detail = MessageUtil.getMessage("pagetitle_saveClicked"); + } + + /** Message to be displayed when Reset Button is clicked. */ + public void resetClicked(ActionEvent ae) throws NullPointerException { + FacesContext context = FacesContext.getCurrentInstance(); + TextField tf1 = (TextField) context.getViewRoot().findComponent("form1:pagetitle:text1"); + TextField tf2 = (TextField) context.getViewRoot().findComponent("form1:pagetitle:text2"); + tf1.setSubmittedValue(null); + tf2.setSubmittedValue(null); + tf2.setValue(null); + text1 = null; + text2 = null; + isRendered = true; + message = MessageUtil.getMessage("pagetitle_elementClicked"); + detail = MessageUtil.getMessage("pagetitle_resetClicked"); + } + + /** Message to be displayed when the PageViews are clicked. */ + public void menuChanged(ActionEvent e) throws AbortProcessingException { + UIComponent c = e.getComponent(); + DropDown menu = (DropDown) c; + isRendered = true; + message = MessageUtil.getMessage("pagetitle_elementClicked"); + detail = MessageUtil.getMessage("pagetitle_viewClicked") + " " + + menu.getValue(); + } + + /** Resets page defaults while navigating to the Index Page. */ + public String showIndex() { + isRendered = false; + text1 = null; + text2 = null; + selectedItem = "View1"; + return "showIndex"; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/progressbar/ProgressBarBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/progressbar/ProgressBarBackingBean.java new file mode 100644 index 0000000..001c9d2 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/progressbar/ProgressBarBackingBean.java @@ -0,0 +1,128 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.progressbar; + +import com.sun.webui.jsf.component.ProgressBar; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + +/** + * + * Backing bean for ProgressBar example. + */ +public class ProgressBarBackingBean { + + // holds progress value. + private int progressRate = 0; + + // holds status string. + private String status = null; + + // Outcome strings used in the faces config. + private final static String SHOW_PROGRESSBAR_INDEX = "showProgressBar"; + + /** Creates a new instance of ProgressBean */ + public ProgressBarBackingBean() { + + } + + /** This method generates the progress value. */ + public int getProgressRate() { + + String task = ""; + if (getComponentInstance() != null) + task = getComponentInstance().getTaskState(); + + if (task != null) { + if (task.equals(ProgressBar.TASK_PAUSED)) { + status = MessageUtil. + getMessage("progressbar_pausedText"); + return progressRate; + + } + if (task.equals(ProgressBar.TASK_CANCELED)) { + status = MessageUtil. + getMessage("progressbar_canceledText"); + return progressRate; + } + } + + progressRate = progressRate + 3; + status = progressRate + MessageUtil. + getMessage("progressbar_percentText"); + + if (progressRate > 99) { + progressRate = 100; + } + + if (progressRate == 100) { + + getComponentInstance().setTaskState(ProgressBar.TASK_COMPLETED); + status = MessageUtil. + getMessage("progressbar_completedText"); + } + + return progressRate; + } + + /** Get the status string for ProgressBar */ + public String getStatus() { + + return status; + } + + /** + * Method to get the ProgressBar instance. + */ + public ProgressBar getComponentInstance() { + FacesContext context = FacesContext.getCurrentInstance(); + UIComponent comp = context.getViewRoot().findComponent("form1:progressBarContentPage:pb1"); + ProgressBar pb = (ProgressBar) comp; + + return pb; + } + + /** + * Action handler when navigating to the progressbar example index. + */ + public String showProgressBarIndex() { + getComponentInstance().setTaskState(ProgressBar.TASK_NOT_STARTED); + progressRate = 0; + status = ""; + return SHOW_PROGRESSBAR_INDEX; + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + + getComponentInstance().setTaskState(ProgressBar.TASK_NOT_STARTED); + progressRate = 0; + status = ""; + return IndexBackingBean.INDEX_ACTION; + } + +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/propertysheet/PropertySheetBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/propertysheet/PropertySheetBackingBean.java new file mode 100644 index 0000000..a2fc30d --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/propertysheet/PropertySheetBackingBean.java @@ -0,0 +1,129 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.propertysheet; + +import javax.faces.event.ValueChangeEvent; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.model.UploadedFile; +import java.io.Serializable; + +/** + * Backing Bean for property sheet example. + */ +public class PropertySheetBackingBean implements Serializable { + + /** Creates a new instance of PropertySheetBackingBean */ + public PropertySheetBackingBean() { + } + + // Holds value for jumpLinkChkBox property. + private boolean jumpLinkChkBox = true; + + // Holds value for requiredLabelChkBox property. + private boolean requiredLabelChkBox = true; + + // Holds value for jumpLink property. + private boolean jumpLink = true; + + // Holds value for requiredlabel. + private String requiredLabel = "true"; + + /** + * this method assigns value to jumpLinks + * property of property sheet tag. + */ + public boolean getJumpLink() { + + return jumpLink; + + } + + /** + * this method assigns value to requiredFields + * property of property sheet tag. + */ + public String getRequiredLabel() { + + return requiredLabel; + } + + /** Getter method for jumpLinkChkBox property. */ + public boolean getJumpLinkChkBox() { + return jumpLinkChkBox; + } + + /** Getter method for requiredLabelChkBox property. */ + public boolean getRequiredLabelChkBox() { + return requiredLabelChkBox; + } + + /** Setter method for jumpLinkChkBox property. */ + public void setJumpLinkChkBox(boolean jumpChkBox) { + this.jumpLinkChkBox = jumpChkBox; + } + + /** Setter method for requiredLabelChkBox property. */ + public void setRequiredLabelChkBox(boolean requiredChkBox) { + this.requiredLabelChkBox = requiredChkBox; + } + + /** valueChangelistener for checkbox that sets jumpLink property. */ + public void jumpMenulistener(ValueChangeEvent event) { + + Boolean newValue = (Boolean) event.getNewValue(); + if (newValue != null + && newValue.booleanValue()) { + jumpLink = true; + } else { + jumpLink = false; + } + + } + + /** valueChangelistener for checkbox that sets requiredLabel property. */ + public void requiredValuelistener(ValueChangeEvent event) { + + Boolean newValue = (Boolean) event.getNewValue(); + if (newValue != null + && newValue.booleanValue()) { + requiredLabel = "true"; + } else { + requiredLabel = "false"; + } + + } + + /** + * Action handler when navigating to the main example index. + */ + public String showExampleIndex() { + + jumpLinkChkBox = true; + requiredLabelChkBox = true; + jumpLink = true; + requiredLabel = "true"; + return IndexBackingBean.INDEX_ACTION; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/resources/Resources.properties b/samples/woodstock/src/com/sun/webui/jsf/example/resources/Resources.properties new file mode 100644 index 0000000..53b2aa6 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/resources/Resources.properties @@ -0,0 +1,991 @@ +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the license at +# https://woodstock.dev.java.net/public/CDDLv1.0.html. +# See the License for the specific language governing +# permissions and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at https://woodstock.dev.java.net/public/CDDLv1.0.html. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# you own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# +# +# A ResourceBundle class containing resources for the example app. + +# +# General resources +# +exampleTitle=Example Application Index +pluginName=Tag Library Examples + +# +# Help resources +# +help_windowTitle=Help - Example Application +help_mastheadAltText=Example Application: Tag Library Examples +help_tooltip=Help on Example Application (Opens a New Window) + + +# +# Primary masthead resources +# +mastheadAltText=Example Application: Tag Library Examples + +# +# Index page resources +# +index_title=Example Application Index +index_summary=This example application demonstrates the User Interface Tag Library. +index_exampleHeader=Example +index_conceptsHeader=Description +index_filesHeader=Files +index_showCodeHeader=Example Source Code +index_noCode=No code to display +index_file=File: +index_noFileName=No file name +index_breadcrumbMouseOver=Back to Example Application Index + +index_buttonName=Button +index_buttonConcepts=Demonstration of button features, including the ability to dynamically enable and disable buttons. +index_alertName=Alert +index_alertConcepts=Demonstration of alert messages that notify users of a condition or error. +index_labelName=Label +index_labelConcepts=Demonstration of label features, including appropriate context-specific styles to use for a hierarchy of appearances with levels of visual weight. +index_cbrbName=Checkbox and Radio Button +index_cbrbConcepts=Demonstration of checkbox and radio button features. +index_textInputName=Text Input +index_textInputConcepts=Demonstration of text area, text field, and password features, including the ability to dynamically enable and disable them with client-side JavaScript technology. +index_tableName=Table +index_tableConcepts=Demonstration of table features, including the ability to page or scroll, sort table data, select items, choose actions, and view alarms. +index_addRemoveName=Add-and-Remove Idiom +index_addRemoveConcepts=Demonstration of add and remove features, including the ability to move list items between the Available list and the Selected list. +index_orderableListName=Orderable List +index_orderableListConcepts=Demonstration of the orderable list, which enables users to rearrange a list of elements. +index_chooserUploader=Chooser Uploader +index_chooserUploaderConcepts=Demonstration of File/Folder Chooser and file Uploader. +index_menuListName=Menu and List +index_menuListConcepts=Demonstration of drop-down menu and scrolling list features, including the ability to dynamically enable and disable them with client-side JavaScript technology. +index_mastheadName=Image and Masthead +index_mastheadConcepts=Demonstration of Image and Masthead features. +index_propertysheet=Property Sheet +index_propertySheetConcepts=Demonstration of Property Sheet. +index_editablelist=Editable List +index_editableListConcepts=Demonstration of Editable List. +index_pagetitleName=Content Page Title +index_pagetitleConcepts=Demonstration of content page title features, including page buttons, page actions, and page views. +index_hyperlink=Hyperlink +index_hyperlinkConcepts=Demonstration of Hyperlink features. +index_statictextName=Static Text +index_statictextConcepts=Demonstration of static text features, including date format masks and custom converter. +index_commonTaskName=Common Tasks Page +index_commonTaskConcepts=Demonstration of usage of common task components:commonTasksSection, commonTasksGroup and commonTask. +index_treeName=Tree +index_treeConcepts=Demonstration of dynamic and client side tree features, including event handling and tree based navigation. +index_progressBar=ProgressBar +index_progressBarConcepts=Demonstration of ProgressBar. +index_wizardName=Wizard +index_wizardConcepts=Demonstration of pop-up window Wizards. +# +# Resources for the Button example +# +button_alertElement=Element Selected +button_alertElementDetail=Element named {0} was selected and has a value of {1}. +button_alertElementDetailNoValue=Element named {0} was selected. +button_title=Button Example +button_alertElement=Element Selected +button_alertElementDetail=Element named {0} was selected and has a value of {1}. +button_alertElementDetailNoValue=Element named {0} was selected. +button_enable=Enable +button_disable=Disable +button_iconButtonLabel=Iconic Button: +button_iconButtonAlt=Iconic Button +button_iconButtonTooltip=Iconic Button +button_primaryButtonLabel=Primary Button: +button_primaryButtonText=Primary +button_primaryButtonTooltip=Primary Button +button_primaryMiniButtonLabel=Primary Mini-Button: +button_primaryMiniButtonText=Primary-Mini +button_primaryMiniButtonTooltip=Primary Mini-Button +button_secondaryButtonLabel=Secondary Button: +button_secondaryButtonText=Secondary +button_secondaryButtonTooltip=Secondary Button +button_secondaryMiniButtonLabel=Secondary Mini-Button: +button_secondaryMiniButtonText=Secondary-Mini +button_secondaryMiniButtonTooltip=Secondary Mini-Button +button_testCase_title=Test Cases +button_testCase_disableAll=Disable All +button_testCase_enableAll=Enable All +button_testCase_submit=Submit Page to Show State Is Maintained +button_resultsTitle=Button Example Results +button_breadcrumbMouseOver=Back to Button Example +button_resultsHelpText=Click the Back button to return to the Button example, and see that state is maintained. +button_backButton=Back +button_resultEnabled=The {0} button is enabled. +button_resultDisabled=The {0} button is disabled. + +# +# Resources for the alert example +# +alert_title=Alert Example +alert_inlineTitle=Inline Alert Example +alert_inlineButton=Inline +alert_fullpageTitle=Full-Page Alert Example +alert_fullpageButton=Full Page +alert_tryAgain=Try Again +alert_tryAgainToolTip=Try to guess the number again +alert_backToExample=Back to Index +alert_backToExampleToolTip=Go back to the example Index +alert_line1Text=I am thinking of a number between 1 and 10 (inclusive). Can you guess the number in 3 attempts? +alert_guess=Guess: +alert_okButton=OK +alert_restartButton=Restart +alert_textFieldTitle=Number Entry Field +alert_number=The number was {0}. +alert_sumCongrats=Congratulations! You got it right! +alert_sumWrong=Game over. Better luck next time. +alert_sumLastChance=Incorrect Number! This is your last chance! +alert_sumTryAgain=Incorrect Number! Try again. +alert_sumException=You must type a number between 1 and 10! +alert_sumExceptionWithHelp=You must type a number between 1 and 10!
    Click the Try Again button to continue with this game or start a new one if this game is over. +alert_detHigher=Type a higher number. +alert_detHigherLastChance=This is your last chance! Type a higher number.
    Click the Try Again button to continue with this game or start a new one if this game is over. +alert_detHigherTryAgain=Try again. Type a higher number.
    Click the Try Again button to continue with this game or start a new one if this game is over. +alert_detLower=Type a lower number. +alert_detLowerLastChance=This is your last chance! Type a lower number.
    Click the Try Again button to continue with this game or start a new one if this game is over. +alert_detLowerTryAgain=Try again. Type a lower number.
    Click the Try Again button to continue with this game or start a new one if this game is over. +alert_congratHeader=Congratulations! +alert_incorrectNumHeader=Incorrect Number! +alert_gameOverHeader=Game over. +alert_number=The number was {0}. +alert_numberCongrats=You got it right! The number was {0}.
    Click the Try Again button to continue with this game or start a new one if this game is over. +alert_numberWrong=Better luck next time. The number was {0}.
    Click the Try Again button to continue with this game or start a new one if this game is over. +alert_breadcrumbMouseOver=Back to Alert Example Index +alert_helpLinkText=More on alert messages +alert_helpLinkTooltip=Help on Alert Example (Opens a New Window) +alert_helpLinkMouseOver=Help on Alert Example (Opens a New Window) +alert_helpWindowText=

    The alert messages demonstration uses a game of "guess a number" to show how alert messages should appear to the user.

    +alert_helpWindowTitle=Alert Messages +alert_close=Close + +# +# Resources for the Label example +# +label_title=Label Example +label_pageHelp=Form elements are often organized hierarchically into groups and subgroups, and labels visually support this hierarchy. Groups have bolder, heavier labels. Individual elements within groups have lighter labels. +label_morePageHelp=More about the label example +label_pizza=Pizza Toppings (Level 1) +label_veggie=Vegetarian Toppings (Level 2) +label_meat=Meat Toppings +label_requiredLabel=Indicates required field +label_olives=Olives (Level 3) +label_mushrooms=Mushrooms (Level 3) +label_pepperoni=Pepperoni +label_sausage=Sausage +label_anchovies=Anchovies +label_noAnchovies=Anchovies not available! +label_phoneNumber=Phone Number: +label_phoneTooltip=For simplicity, any positive integer less than 1000 is a valid phone number. +label_address=Delivery Address: +label_addressTooltip=For simplicity, any value but \"XXX\" is a valid address. +label_invalidPhone=Phone number must be a positive integer less than 1000 +label_invalidAddress=Delivery address cannot be {0} +label_orderButton=Place Order +label_resetButton=Reset +label_helpTooltip=Help on Label Example (Opens a New Window) +label_helpWindowTitle=Help - Label Example +label_helpWindowText=

    The Label example shows how to hierarchically organize form elements into groups and subgroups, and to visually support this hierarchy. Groups have bolder, heavier labels. Individual elements within groups have lighter labels. Labels can indicate when user input is required and when validation of that input fails.

    +label_close=Close +label_genericError=Please correct errors on the page. +label_resultsTitle=Label Example Results +label_breadcrumbMouseOver=Back to Label Example +label_resultsHelpText=Click the Back button to return to the Label example and order another pizza! +label_backButton=Back +label_plainPizza=Plain cheese pizza +label_toppingsPizza=Pizza with these toppings: +label_pepperoniResult=pepperoni +label_sausageResult=sausage +label_mushroomResult=mushrooms +label_oliveResult=olives +label_whereResult=Delivered to {0}, phone number {1} + +# +# Resources for the Checkbox and Radiobutton example +# +cbrb_title=Checkbox and Radio Button Example +cbrb_checkboxLabel=Checkbox: +crcb_redCheckbox=Red +crcb_enable=Enable +cbrb_radiobuttonLabel=Radio Button: +cbrb_radiobuttonImagesLabel=Radio Button Image: +cbrb_radioButton1=Server +cbrb_radioButton2=Volume +cbrb_radioButton3=Pool +cbrb_resetButtonLabel=Reset +cbrb_testCase_title=Test Cases +cbrb_testCase_toggleCheckboxState=Toggle Enable/Disable State of Checkbox +cbrb_testCase_toggleRadiobuttonState=Toggle Enable/Disable State of RadioButton +cbrb_testCase_toggleRadiobuttonImageState=Toggle Enable/Disable State of RadioButton Image +cbrb_testCase_disableAll=Disable All +cbrb_testCase_enableAll=Enable All +cbrb_submitButtonLabel=Submit Page to Show State Is Maintained +cbrb_resultsTitle=Checkbox and Radio Button Example Results +cbrb_resultsHelpText=Click the Back button to return to the Checkbox and RadioButton example, and see that state is maintained. +cbrb_backButton=Back +cbrb_breadcrumbMouseOver=Back to Checkbox and RadioButton Example +cbrb_selected=selected +cbrb_notSelected=not selected +cbrb_disabled=disabled +cbrb_enabled=enabled +cbrb_result={0} {1} is {2} and {3} +cbrb_checkboxResult=Checkbox +cbrb_radioButtonResult=Radio Button +cbrb_radioButtonImageResult=Radio Button Image + +# +# Resources for the Text Input example +# +field_title=Text Input Example +field_passwordLabel=Password: +field_passwordTitle=Password +field_passwordTitleDisabled=Password (Disabled) +field_textAreaLabel=Text Area: +field_textAreaTitle=Text Area +field_textAreaTitleDisabled=Text Area (Disabled) +field_textFieldLabel=Text Field: +field_textFieldTitle=Text Field +field_textFieldTitleDisabled=Text Field (Disabled) +field_disable=Disable +field_enable=Enable +field_testCaseTitle=Test Cases +field_testCaseToggleTextFieldState=Toggle Enable/Disable State of Text Input +field_testCaseTogglePasswordState=Toggle Enable/Disable State of Password +field_testCaseToggleTextAreaState=Toggle Enable/Disable State of Text Area +field_testCaseDisableAll=Disable All +field_testCaseEnableAll=Enable All +field_presetFieldsButton=Preset Fields +field_submitButton=Submit +field_resultsPageHelpText=Click the Back button to return to the Text Input example, and see that state is maintained. +field_resultsPageTitle=Text Input Results +field_breadcrumbMouseOver=Back to Text Input Example +field_backButton=Back +field_fieldResult={0} is {1} and has a value of {2} +field_disabled=disabled +field_enabled=enabled +field_dropDownToolTip=Select an Option + +# +# Resources for the Table example +# +table_breadcrumbMouseOver=Back to Table Index +table_title=Table Index +table_mainTitle=Main Example +table_tableTitle=Table +table_tableConcepts=This example shows a sortable table with actions, filters, and preferences. +table_LastName=Last Name +table_FirstName=First Name +table_ActionDelete=Delete +table_Action1=Action 1 +table_Action2=Action 2 +table_Action3=Action 3 +table_Action4=Action 4 +table_ActionsMenuTitle=More Actions +table_Actions=Actions +table_taskStatus=Task Status +table_embeddedActionMsg=Embedded Action Selected: Parameter = +table_moreActionsMsg=More Actions Menu Selected +table_tableActionMsg=Table Action Selected +table_filterAllItems=All Items +table_filter1=Filter 1 +table_filter2=Filter 2 +table_filterCustom=Custom +table_customFilterLabel=Show only rows containing last name: +table_tldTitle=TLD Examples +table_actionsTitle=Actions +table_actionConcepts=This example shows how to add Actions using a JSF facet. In this example, four buttons and a drop down menu are added to the top and bottom table action bars. When the page is initially displayed, all actions are disabled. These actions are only enabled once the user has selected at least one checkbox. When the checkboxes are unselected (e.g., when clicking the deselect all button), actions are disabled again. When the user clicks on a checkbox, a Javascript function (named \"disable\") is invoked via the onClick event. The Javascript setTimeout function is used to ensure checkboxes are selected immediately, instead of waiting for the Javascript function to complete. See the \"Actions\" example class. +table_alarmsTitle=Alarms +table_alarmsConcepts=This example shows how to add alarms to table data cells. The table data cell will appear highlighted when the alarm attribute of tableColumn is set to true. See the \"Name\" example class. +table_basicTitle=Basic Table +table_basicConcepts=This example shows how to create a basic table. +table_customTitle=Custom Title +table_customConcepts=This example shows how to create a custom table title. When using the title attribute, as shown in the Basic Table example, the component provides a default title implementation which may include information regarding paginated rows and applied filters. However, the developer may plug in their own components if desired using a JSF facet. +table_dynamicGroupTitle=Dynamic Group Table +table_dynamicGroupConcepts=This example shows how to create a binding to a backing bean to dynamically create a table layout. See the \"DynamicGroupTableBean\" example class. +table_dynamicTitle=Dynamic Table +table_dynamicConcepts=This example shows how to create a binding to a backing bean to dynamically create a group table layout. See the \"DynamicTableBean\" example class. +table_embeddedActionsTitle=Embedded Actions +table_embeddedActionsConcepts=This example shows how to add embedded actions to a table. If the tableColumn component contains components used as embedded actions (e.g., add, delete, etc.), set the embeddedTableActions property to true and an action separator bar will appear between each child component per UI guidelines. +table_emptyCellsTitle=Empty Cells +table_embeddedActionsConcepts1=This example shows how to add an empty table cell icon (dash icon) when a table cell is inapplicable or unexpectedly empty. UI guidelines suggest not to use this for a value that is truly null, such as an empty alarm cell or a comment field which is blank, neither of which should have the icon. Further, the icon is not used for cells that contain user interface elements such as checkboxes or drop-down lists when these elements are not applicable. Instead, the elements are simply not displayed. +table_embeddedActionsConcepts2=Note: In this example, the emptyCell attribute is intentionally set to true every 5th row. However, it's up to the developer to decide how to test if the cell is truly empty. For example, you could use this syntax: emptyCell=\"# {name.value.last == null}\" +table_filterTitle=Filter +table_filterConcepts1=Basic filters are precanned options selectable via the filter drop down menu, which is defined by a JSF facet. For custom filters, the Filter panel is used. UI guidelines recommend adding a \"Custom Filter\" option to the basic options provided via the filter menu. When the \"Custom Filter\" menu is selected, an embedded panel in the table is opened, displaying facet contents provided by the developer. After the filter has been applied, UI guidelines recommend adding a \"Custom Filter Applied\" option indicating that a custom filter has been applied. Further, UI guidelines also state that the table title should indicate that a basic or custom filter has been applied. Thus, text is added to the table title via the filter attribute of the table tag. +table_filterConcepts2=Note: This functionality requires the filterId of the table component to be set. In addition, the selected value must be set as well to restore the default selected value when the embedded filter panel is closed. +table_groupTableTitle=Group Table +table_groupTableConcepts1=This example shows how to create groups of data in the same table. In a basic table, each column typically has a header and perhaps a footer. However, in a group table, each data group may have its own overall header and footer. Further, the table may display its own column footers and an overall footer below all data groups. +table_groupTableConcepts2=UI guidelines recommend that column headers and table column footers are only rendered once. Column headers typically appear at the the top of the table, above all row groups. And table column footers appear only at the bottom of the table, below all row groups. Therefore, the headerText and tableFooterText attributes only need to be defined for the first tableRowGroup component used in the table. Additional tableColumn attributes should be used for each tableRowGroup component to specify functionality, such as selectId and sort. This will allow column headers to sort on all row groups at once, for example. See the \"TableBean\" example class. +table_groupTableConcepts3=Note: UI guidelines recommend items should be unselected when no longer in view. Using the TableSelectPhaseListener object ensures that this scenario does not occur because state is cleared after the rendering phase. Although pagination is not used for a group table, we are still using the TableSelectPhaseListener object for this example. See \"Select\" example class. +table_tableFooter=Table Footer +table_groupFooter=Group Footer +table_groupHeader=Group Header +table_columnFooter=Column Footer +table_tableColumnFooter=Table Column Footer +table_alignedRight=Right-Aligned Text +table_hiddenSelectedRowsTitle=Hidden Selected Rows +table_hiddenSelectedRowsConcepts1=This example shows a column of checkbox components used to select multiple table rows. Dynamic row highlighting is set by invoking the initAllRows function when ever the state of the checkbox changes. This state is maintained via the selected attribute of the tableRowGroup tag. +table_hiddenSelectedRowsConcepts2=Note: UI guidelines recommend items should be unselected when no longer in view. However, there are cases when maintaining state across pages is necessary. When maintaining state, set the selectedRows attribute for the table tag. This will display text in the table title and footer indicating the number of selected rows hidden from view. See the \"Select\" example class. +table_liteTitle=Lite Table +table_liteConcepts=This example shows how to create a basic table that looks lighter weight, generally by omitting the shading around the table and in the title bar. +table_nestedColumnsTitle=Multiple Headers & Footers +table_nestedColumnsConcepts1=This example shows how the table behaves when columns are nested. +table_nestedColumnsConcepts2=Note: Currently, only the footerText, headerText, and tableFooterText attributes of TableColumn are supported in this configuration. Sorting is currently not supported for Multiple Headers & Footers. +table_paginatedTableTitle=Paginated Table +table_paginatedTableConcepts1=This example shows how to create a paginated table. The default number of rows to be displayed for a paginated table is 25 per page. However, the developer may override this value via the rows attribute. +table_paginatedTableConcepts2=Note: The rows attribute is used only for paginated tables. +table_preferencesTitle=Preferences +table_preferencesConcepts1=This example shows how to add Preferences via the Preferences panel. The Preferences panel toggle button is shown only when using a JSF facet. This button opens an embedded panel in the table, displaying facet contents provided by the developer. +table_preferencesConcepts2=In this example, the Preferences panel is used to set the number of paginated rows via the rows attribute of tableRowGroup. See the \"Preferences\" example class. +table_selectMultipleRowsTitle=Select Multiple Rows +table_selectMultipleRowsConcepts1=This example shows a column of checkbox components used to select multiple table rows. Dynamic row highlighting is set by invoking the initAllRows function when ever the state of the checkbox changes. This state is maintained via the selected attribute of the tableRowGroup tag. Note that this example does not maintain state across paginated pages. +table_selectMultipleRowsConcepts2=Note: UI guidelines recommend items should be unselected when no longer in view. Using the TableSelectPhaseListener object ensures that this scenario does not occur because state is cleared after the rendering phase. See the \"Select" example class. +table_selectSingleRowTitle=Select Single Row +table_selectSingleRowConcepts1=This example shows a column of radiobutton components used to select a single table row. Dynamic row highlighting is set by invoking the initAllRows function when ever the state of the radiobutton changes. This state is maintained via the selected attribute of the tableRowGroup tag. Note that this example does not maintain state across paginated pages. +table_selectSingleRowConcepts2=Note: UI guidelines recommend items should be unselected when no longer in view. Using the TableSelectPhaseListener object ensures that this scenario does not occur because state is cleared after the rendering phase. See the \"Select" example class. +table_spacerColumnTitle=Spacer Column +table_spacerColumnConcepts=When displaying properties for a single object, a property table might be useful. A property table typically includes two data columns. The first column identifies the properties of the object, and the second column displays the values for each of the properties. The remaining width of the table displays a third, blank column to keep the first two columns next to one another while still having the table fill the full screen width. Leave the column heading of the third and final column blank, and display no data in this column. Set a value for the width attribute to achieve the desired spacing. +table_sortableTableTitle=Sortable Table +table_sortableTableConcepts1=This example shows how to add table sorting. Note that the value binding objects used when sorting must be the proper type. For example, when the String values \"2\" and \"11\" are sorted, \"11\" is displayed before \"2\". Instead, developers should sort using objects such as Number, Character, Date, Boolean, etc. +table_sortableTableConcepts2=Note: UI guidelines recommend not setting a default initial sort; however, developers may do so using the addSort(SortCriteria) method of TableRowGroup. When the table is rendered, data will be sorted and the primary sort column highlighted. +table_sortableTableConcepts3=Note: Either a FieldKey id or value binding may be used to define criteria for sorting the contents of TableDataProvider. However, when sorting a column of checkboxes/radiobuttons, a value binding must be used because values are external to the data (i.e., TableDataProvider does not contain FieldKey ids for a selected checkbox value). +table_ok=OK +table_cancel=Cancel + +# +# Resources for the Add Remove example +# +addremove_title=Add-and-Remove Idiom Example +addremove_selectAuthors=Favorite Authors +addremove_selectBooks=Favorite Books +addremove_available=Available: +addremove_selected=Selected: +addremove_breadcrumbMouseOver=Back to Add-and-Remove Idiom Example +addremove_resultsTitle=Add-and-Remove Idiom Example Results +addremove_author1=Richard Russo +addremove_author2=Harper Lee +addremove_author3=Ernest Hemingway +addremove_author4=John Steinbeck +addremove_author5=Michael Cunningham +addremove_author6=Michael Chabon +addremove_author7=Frank McCourt +addremove_author8=Thornton Wilder +addremove_author9=Philip Roth +addremove_author10=Michael Shaara +addremove_author1v=Robin Moore +addremove_author2v=Lt Gen Harold Moore +addremove_author3v=Ron Smith +addremove_author4v=Tammy Bruce +addremove_author5v=William J. O'Neill +addremove_author6v=Dennis Smith +addremove_author7v=James McPherson +addremove_author8v=Fredrick Downs +addremove_author9v=Joseph Horrigan and Luc Robataille +addremove_author10v=Danna Scott +addremove_book1=Empire Falls +addremove_book2=To Kill a Mockingbird +addremove_book3=The Old Man and the Sea +addremove_book4=Grapes of Wrath +addremove_book5=Hours +addremove_book6=The Amazing Adventures of Kavalier and Clay +addremove_book7=Angela's Ashes: A Memoir +addremove_book8=Our Town: A Play in Three Acts +addremove_book9=American Pastoral +addremove_book10=The Killer Angels +addremove_book1v=The Hunt for Bin Laden - Task Force Dagger +addremove_book2v=We Were Soldiers Once... and Young +addremove_book3v=Yankees - A Century of Greatness +addremove_book4v=The Death of Right and Wrong +addremove_book5v=24 Essentials for Investment Success +addremove_book6v=Report from Ground Zero +addremove_book7v=Hallowed Ground: A Walk at Gettysburg +addremove_book8v=The Killing Zone - My Life in the Vietnam War +addremove_book9v=Strength, Conditioning and Injury Prevention for Hockey +addremove_book10v=Boxing - The Complete Guide to Training and Fitness +addremove_showVertical=Show Vertical Orientation +addremove_showHorizontal=Show Horizontal Orientation +addremove_testCaseMenuLabel=Select Test Case: +addremove_testCaseTitle=Actions +addremove_testCaseSetInitValues=Set Initial Selections +addremove_testCaseShowSelections=Show Selections +addremove_error=Selection Required +addremove_noAuthorSelection=Select at least one author. +addremove_noBookSelection=Select at least one book. +addremove_tableCaption=User Selections: +addremove_tableHeading1=Author +addremove_tableHeading2=Book Title +addremove_resultsHelpText=Click the Back button to return to the Add Remove example, and see that state is maintained. +addremove_backButton=Back +addremove_presetButton=Preset List +addremove_showItemsButton=Show Selected Items + +# +# Resources for the Orderable List example +# +orderablelist_breadcrumbMouseOver=Back to Orderable List Example +orderablelist_title=Orderable List +orderablelist_helpTitle=What is your favorite flavor? Arrange the items in the list. +orderablelist_resultsTitle=Orderable List Results +orderablelist_resultsHelpText=Click the Back button to return to the Orderable List example, and see that state is maintained. +orderablelist_error=Error! +orderablelist_tableHeading=User Selections: +orderablelist_columnHeading=Flavors: +orderablelist_listHeading=Flavors: +orderablelist_resetButton=Reset Order +orderablelist_showItemsButton=Show Ordered Results +orderablelist_flavor1=Strawberry +orderablelist_flavor2=Vanilla +orderablelist_flavor3=Chocolate +orderablelist_flavor4=Coffee +orderablelist_flavor5=Black Raspberry +orderablelist_flavor6=Peach +orderablelist_flavor7=Chocolate Chip +orderablelist_flavor8=Mint Chocolate Chip +orderablelist_flavor9=Coconut Chocolate Chip +orderablelist_flavor10=Mocha Chip +orderablelist_flavor11=Butter Crunch +orderablelist_flavor12=Butter Pecan +orderablelist_flavor13=Maple Walnut +orderablelist_flavor14=Rocky Road +orderablelist_flavor15=Oreo Cookie +orderablelist_flavor16=Cookie Dough +orderablelist_flavor17=Mud Pie +orderablelist_backButton=Back + +# +# Resources for the file uploader/chooser example +# +chooserUploaderIndex_fileUploaderhyperlink=File Uploader +chooserUploaderIndex_folderChooserhyperlink=Folder Chooser +chooserUploaderIndex_fileChooserhyperlink=File Chooser +chooserUploaderIndex_chooserUploaderhyperlink=Chooser and Uploader +chooserUploaderIndex_fileUploaderTooltip=File Uploader +chooserUploaderIndex_folderChooserTooltip=Folder Chooser +chooserUploaderIndex_fileChooserTooltip=File Chooser +chooserUploaderIndex_chooserUploaderTooltip=Chooser and Uploader +chooserUploaderIndex_fileUploaderText=File Uploader: +chooserUploaderIndex_folderChooserText=Folder Chooser: +chooserUploaderIndex_fileChooserText=File Chooser: +chooserUploaderIndex_chooserUploaderText=Chooser and Uploader: +chooserUploader_invalidDir=Invalid directory: You have specified invalid directory name. +chooserUploader_permissionDenied=Permission denied: You do not have write permission. +chooserUploderIndex_title=Chooser Uploader Example Index +chooseruploader_summary=Validator Exception +uploader_label=File uploader with popup window version of file/folder chooser. +uploader_textFieldlabel=Destination Directory on Server: +uploader_buttonTextFolder=Browse Server... +uploader_uploadLabel=Choose File to Upload: +uploader_uploadButtonCaption=Upload File +uploader_folderButtonToolTip=Browse Server +uploader_uploadButtonToolTip=Upload File +uploader_fileChooserText1=Click +uploader_fileChooserLink=File Chooser +uploader_fileChooserText2=to open filechooser popup window and you can view the uploaded file. +folderChooserPopup_title=Popup window version of Folder Chooser +folderChooser_buttonTooltip=Select Folder +folderChooser_buttonCaption=Select Folder +fileChooserPopup_closeButtonCaption=Close +fileChooserPopup_closeButtonTooltip=Close +folderChooser_textLabel=Selected Folder: +fileChooserPopup_title=Popup window version of File Chooser +uploader_fileChooserLinkTooltip=File Chooser +uploader_textFieldTooltip=Directory to upload File +uploaderPopup_title=Chooser and Uploader +chooserUploader_title=Chooser Uploader Example Index +chooserUploader_breadcrumbMouseOver=Back to Chooser Uploader Example +fileChooser_title=File Chooser +fileChooser_chooseButtonCaption=Choose File +fileChooser_chooseButtonCaptionTooltip=Choose File(s) +fileChooser_chooseFileText=Selected File(s) Path: +fileChooser_emptyFieldAlert=No File Selected! +uploader_title=File Uploader +fileUploader_chooseFileText=File Uploaded To: +fileUploader_title=File Uploader +folderChooser_title=Folder Chooser +folderChooser_chooseButtonCaption=Choose Folder +folderChooser_chooseButtonCaptionTooltip=Choose Folder +folderChooser_choosefolderText=Selected Folder Path: +folderChooser_emptyFieldAlert=No Folder Selected! +chooserUploader_invalidFile=Empty File: Specified file is of zero size. + +# +# Resources for the Menu and List example. +# +menu_title=Menu and List Example +menu_alertElement=Element Selected +menu_alertElementDetail=Element named {0} was selected and has a value of {1}. +menu_enable=Enable +menu_enableOption=Enable 'Option A' +menu_jumpMenuHelp=Used for action menus that do not use a Go button to initiate actions. +menu_jumpMenuLabel=Jump Menu: +menu_jumpMenuTitle=Jump Menu +menu_jumpMenuTitleDisabled=Jump Menu (Disabled) +menu_standardMenuHelp=Enables the user to choose a value, and then initiate an action when data entry is complete. +menu_standardMenuLabel=Standard Menu: +menu_standardMenuTitle=Standard Menu +menu_standardMenuTitleDisabled=Standard Menu (Disabled) +menu_selectableListLabel=Scrolling List: +menu_selectableListTitle=Scrolling List +menu_selectableListTitleDisabled=Scrolling List (Disabled) +menu_option0=(No Option) +menu_option1=Option 1 +menu_option2=Option 2 +menu_option3=Option 3 +menu_option4=Option 4 +menu_option5=Option 5 +menu_option6=Option 6 +menu_optiona=Option A +menu_optionb=Option B +menu_optionc=Option C +menu_optiond=Option D +menu_optione=Option E +menu_optionf=Option F +menu_option1Disabled=Option 1 (Disabled) +menu_option2Disabled=Option 2 (Disabled) +menu_option3Disabled=Option 3 (Disabled) +menu_option4Disabled=Option 4 (Disabled) +menu_option5Disabled=Option 5 (Disabled) +menu_option6Disabled=Option 6 (Disabled) +menu_optionaDisabled=Option A (Disabled) +menu_optionbDisabled=Option B (Disabled) +menu_optioncDisabled=Option C (Disabled) +menu_optiondDisabled=Option D (Disabled) +menu_optioneDisabled=Option E (Disabled) +menu_optionfDisabled=Option F (Disabled) +menu_optionGroup1=Option Group 1 +menu_optionGroup2=Option Group 2 +menu_action0=Actions +menu_action1=Action 1 +menu_action2=Action 2 +menu_action3=Action 3 +menu_action4=Action 4 +menu_action5=Action 5 +menu_action6=Action 6 +menu_actiona=Action A +menu_actionb=Action B +menu_actionc=Action C +menu_actiond=Action D +menu_actione=Action E +menu_actionf=Action F +menu_action1Disabled=Action 1 (Disabled) +menu_action2Disabled=Action 2 (Disabled) +menu_action3Disabled=Action 3 (Disabled) +menu_action4Disabled=Action 4 (Disabled) +menu_action5Disabled=Action 5 (Disabled) +menu_action6Disabled=Action 6 (Disabled) +menu_actionaDisabled=Action A (Disabled) +menu_actionbDisabled=Action B (Disabled) +menu_actioncDisabled=Action C (Disabled) +menu_actiondDisabled=Action D (Disabled) +menu_actioneDisabled=Action E (Disabled) +menu_actionfDisabled=Action F (Disabled) +menu_actionGroup1=Action Group 1 +menu_actionGroup2=Action Group 2 +menu_testCase0=Test Cases +menu_testCase1=Disable Menus and List +menu_testCase2=Disable Menu and List Options +menu_testCase3=Enable Menus and List +menu_testCase4=Enable Menu and List Options +menu_warning=UI guidelines specify that state is not maintained for disabled options. +menu_breadcrumbMouseOver=Back to Menu and List Example +menu_backButton=Back +menu_submitButton=Submit List and Menu Selections +menu_resultsPageTitle=Menu and List Selections +menu_resultsPageHelpText=Click the Back button to return to the Menu and List example, and see that state is maintained. +menu_resultsPageSelectionLabel=The values of the options you selected are: +menu_staticText=The value of the selected option is +menu_noOption=No option is selected. + +# +# Resources for the Image and Masthead example +# +masthead_title=Image and Masthead Example +masthead_titleToolTip=Back to Image and Masthead Index +masthead_masthead1Title=Masthead with Attributes +masthead_masthead2Title=Masthead with Facets +masthead_masthead3Title=Images and ImageHyperlink +masthead_breadcrumbMouseOver=Back to Image and Masthead Index +masthead_title1ToolTip=Back to Masthead with Attributes page +masthead_title2ToolTip=Back to Masthead with Facets page +masthead_pageTitle1=Primary Masthead with Attributes +masthead_helpText1=This example shows the use of the <ui:masthead> tag with values being assigned to its various attributes.
    This example does not make use of the facets available with the masthead component to specify the status area content. +masthead_pageTitle2=Masthead with Status Area Facet +masthead_helpText2=This example shows the use of the <ui:masthead> tag which employs facets to specify the status area content. +masthead_pageTitle3=Images and ImageHyperlink +masthead_helpText3=This example shows the use of the <ui:image> and <ui:imageHyperlink> tags. +masthead_pageTitle4=Pop up window with a Secondary Masthead +masthead_helpText4=This example shows the use of <ui:masthead> tag to display a Secondary Masthead. +masthead_toolTip1=Masthead with Attributes +masthead_toolTip2=Masthead with Facets +masthead_toolTip3=Images and ImageHyperlink +masthead_consoleLink=Console Link +masthead_versionLink=Display Product Version.(Open a new window) +masthead_logoutLink=Logout of this session +masthead_helpLink=Help Link +masthead_link=Link to Secondary Masthead +masthead_linkToolTip=Opens a Popup window with a Secondary Masthead +masthead_notificationmsg=Task Completed +masthead_cb1Text=Show Notification Info in Masthead +masthead_cb2Text=Show Jobs Running Info in Masthead +masthead_cb3Text=Show Timestamp Info in Masthead +masthead_cb4Text=Show Current Alarms in Masthead +masthead_selectOptions=Select Masthead Options: +masthead_buttonText=Update Masthead +masthead_buttonToolTip=Update Masthead +masthead_popuptitle=Pop up +masthead_closeButton=Close +masthead_closeButtonToolTip=Closes this window +masthead_versiontitle=Version Page +masthead_version=Version 1.0 beta +masthead_copyright=This is where your application copyright notice would appear. +masthead_label1=Example of an image: +masthead_label2=Example of Theme Specific Images: +masthead_label3=Example of an ImageHyperlink: +masthead_imageAltText=Image +masthead_imageToolTip=This is an image +masthead_imageDesc=This is an example of an image icon +masthead_imageMouseOver=The mouse is over the image +masthead_imageMouseOut=The mouse is outside the image +masthead_imageOnClick=The image has been clicked +masthead_imagehyperlinkToolTip=Click to go to www.sun.com +masthead_utilityLink1Text=Sun's Home Page +masthead_utilityLink1ToolTip=Click to open www.sun.com in a new window +masthead_utilityLink2Text=SDN Home +masthead_utilityLink2ToolTip=Click to go to developers.sun.com +masthead_helpLinkClicked=Help link was clicked. +masthead_logoutLinkClicked=Logout link was clicked. +masthead_versionLinkClicked=Version link was clicked. +masthead_consoleLinkClicked=Console link was clicked. +masthead_notificationClicked=The Masthead's Notification message was clicked. +masthead_jobStatusClicked=The Masthead's Job Status href was clicked. +masthead_alarmClicked=The Masthead's Alarm Count href was clicked. +masthead_criticalalarmClicked=The critical count was clicked. +masthead_majoralarmClicked=The major count was clicked. +masthead_minoralarmClicked=The minor count was clicked. +masthead_resultTitle=Image and Masthead Example Result +masthead_backButton=Back + +# +# Resources for property sheet example +# +propertysheet_title=Property Sheet Example +propertysheet_Okbutton=OK +propertysheet_CancelButton=Cancel +propertysheet_textField=Text Field Section +propertysheet_userIdLabel=User ID: +propertysheet_passwordLabel=Password: +propertysheet_chooser=File/Folder Chooser Section +propertysheet_chooseFile=Choose File(s): +propertysheet_orderable=Orderable List Section +propertysheet_addremove=Add - Remove Section +propertysheet_chooseFolder=Choose Folder: +propertysheet_table=Table Section +propertysheet_tableBasic=Basic Table: +propertysheet_pageConfig=Page Configuration +propertysheet_jumpLink=Jump Links: +propertysheet_jumpLinkHelp=Turn on or off the jump links shown at the top of the page. Select or deselect the checkbox. Then, click OK +propertysheet_required=Required Field: +propertysheet_requiredHelp=Turn on or off the required field label shown at the top of the page. Select or deselect the checkbox. Then, click OK +propertysheet_jumpChkBox=Show Jump Links and Back-to-Top Links +propertysheet_requiredChkBox=Show Required Field label +propertysheet_orederableHeading=Flavors +propertysheet_fileChoosertext=File Chooser +propertysheet_folderChoosertext=Folder Chooser +propertysheet_redisplayButton=Redisplay +propertysheet_resulttitle=Property Sheet Result Page +propertysheet_resultlabel=User ID: +propertysheet_backButton=Back + +# +# Resources for the editable list example +# +editablelist_title=Editable List Example +editablelist_Okbutton=OK +editablelist_fieldlabel=Assign Role: +editablelist_listlabel=User's Role +editalbelist_toolTip=List of roles for user +editablelist_chkboxList=Set list on top +editablelist_chkboxSort=Set list sorted +editablelist_string=The string must consist of letters only. +editablelist_summary=Validator Exception +editablelist_labelText=Manage user roles by adding/removing roles. +editablelist_listvalidate=You must enter at least five items. +editablelist_redisplayButton=Redisplay +editablelist_resulttitle=Editable List Result Page +editablelist_resultlabel=Role's Assigned To User: +editablelist_helpText=Roles must consist of letters only. +editablelist_backButton=Back + +# +# Resources for the Page Title example +# +pagetitle_title=Content Page Title Example +pagetitle_helpText=This example shows the use of the <ui:contentPageTitle> tag. +pagetitle_save=Save +pagetitle_reset=Reset +pagetitle_hyperlink=Go to www.sun.com +pagetitle_hyperlinkToolTip=Click to go to www.sun.com +pagetitle_dropDown=View: +pagetitle_label1=Name: +pagetitle_label2=Phone #: +pagetitle_elementClicked=Element Selected +pagetitle_saveClicked=PageButton with value Save was clicked. +pagetitle_resetClicked=PageButton with value Reset was clicked. +pagetitle_viewClicked=View menu was changed to value +pagetitle_view1=View 1 +pagetitle_view2=View 2 +pagetitle_view3=View 3 +pagetitle_error=Error +pagetitle_detail=Name is a required field. + +# +# Resources for the Hyperlink example +# +hyperlink_title=Hyperlink Example +hyperlink_textSubmit=Hyperlink that submits the form. +hyperlink_textlinkSubmit=Submit this Page +hyperlink_linkSubmittoolTip=Submit this Page +hyperlink_textPage=Hyperlink that goes to another page. +hyperlink_textlinkPage=Go to Mozilla.org +hyperlink_linkPagetoolTip=Go to Mozilla.org +hyperlink_textBody=Body of a hyperlink to render text with image. +hyperlink_textlinkBody=Go to Sun.com +hyperlink_imageTooltip=Go to Sun.Com +hyperlink_imageText=Go to Sun.Com +hyperlink_textImmediate=Hyperlink with immediate attribute set to true. No validation will happen for this page. +hyperlink_textlinkImmediate=Click here to check immediate attribute +hyperlink_linkImmediatetoolTip=Click here to check immediate attribute of hyperlink +hyperlink_textlabel=User Name: +hyperlink_resulttitle=Hyperlink Result Page +hyperlink_resultlabel=User Name: +hyperlink_resultname=User Name: +hyperlink_anchorlinktext=Go to Top +hyperlink_anchortoolTip=Go to Top +hyperlink_anchortext=Hyperlink as an anchor tag. +hyperlink_buttonok=OK +hyperlink_chkBoxlabel=Disable all hyperlinks +hyperlink_resultparam=Additional Request Parameter Value: +hyperlink_paramtext=When this link is clicked, the page will be submitted and the request parameter map will have one additional item in it. +hyperlink_paramlinktext=Click here to see additional request parameters on result page +hyperlink_paramlinktooltip=Click here to see additional request parameters on result page +hyperlink_imagelinktext=Image as hyperlink. +hyperlink_checkboxHelptext=Select the checkbox to disable all hyperlinks and then click OK. +hyperlink_summary=Error +hyperlink_detail=A value is required for User Name. +hyperlink_disableButton=Disable All Hyperlinks +hyperlink_enableButton=Enable All Hyperlinks +hyperlink_imageTextHeading=Image Hyperlink With Text +hyperlink_pageHeading=Page Swap Hyperlink +hyperlink_imageHeading=Image Hyperlink +hyperlink_submitHeading=Submit Page Hyperlink +hyperlink_anchorHeading=Anchor Hyperlink +hyperlink_immediateHyperlink=Immediate Hyperlink +hyperlink_paramHeading=Parameterized Hyperlink +hyperlink_backButton=Back + +# +# Resources for the Static Text example +# +statictext_title=Static Text Example +statictext_helpText=This example shows the use of the <ui:staticText> tag. +statictext_text=This is a staticText example +statictext_imageMouseOver=The mouse is over the staticText +statictext_imageMouseOut=The mouse is outside the staticText +statictext_imageOnClick=The staticText has been clicked +statictext_label=Static Text with Default Converter +statictext_helpText1=Static Text using default JSF converter to convert Date object to String. +statictext_label1=Date Mask 1 (yyyy.MM.dd G HH:mm:ss z): +statictext_label2=Date Mask 2 (MM/dd/yyyy HH:mm:ss z): +statictext_label3=Date Mask 3 (MM/dd/yy): +statictext_label4=Static Text with Custom Converter +statictext_helpText2=Static Text using custom converter to convert an Employee object to String. +statictext_label5=Hover and Click +statictext_helpText3=Click/Move mouse over Static Text to see its value changing. +statictext_firstname=John +statictext_lastname=Dickson +statictext_designation=System Analyst +statictext_errorMessage1=Not a employee: +statictext_errorMessage2=Value must be of the format 'FirstName LastName Designation' + +# +# Resources for the Common Tasks example. +# +commontask_title=Common Task components Example +commontask_task1=Understanding the 6920 systems +commontask_task2=Create a storage volume +commontask_task2infotitle=Create a storage volume +commontask_task2infotext=Creates a new storage volume on the disk. Specify all the necessary appropriate information to get the new storage volume up and running. +commontask_task3=Create a storage volume +commontask_task3infotitle=Create using a facet +commontask_task3infotext=This common task was created using the "taskAction" facet. +commontask_task4=Add a storage pool +commontask_task5=Reserve space store snapshot +commontask_task5infotitle=Reserve space store snapshot +commontask_task5infotext= Click on this task to reserve a space store snapshot. Select the disk on which you want the reservation to be done. +commontask_task6=Add a feature license +commontask_task7=Display License compliance +commontask_task7infotitle=Display License Compliance +commontask_task7infotext=Click on this task to see the licenses this webapp complies to. +commontask_task8=Reserve a data snapshot +commontask_task9=Create a mirrored volume +commontask_task9infotitle=Create a mirrored volume +commontask_task9infotext=What: Understand the meanings and relationships among the system's storage elements. These include logical elements (storage domains, volumes, storage pools, virtual disks, and snapshots) and physical elements (storage arrays, storage trays and disks). +commontask_task10=Delete a custom storage profile +commontask_task10infotitle=Delete a custom storage profile +commontask_task10infotext=Select this task to delete a storage profile that you have created. Note that the default profile is always needed and cannot be deleted. +commontask_index=Return to example application index +commontask_group1=First time Use +commontask_group2=Configuration +commontask_group3=Licensing +commontask_group4=Copying data +commontask_group5=Example Application index +commontask_infolinktext=Click here to know more +commontask_infolinktextfacet=Replaced standard hyperlink with facet +commontask_infopanelfacet=This info panel was created using a facet. This facet has a panel group which contains an image and static text component as children. +commontask_indexinfotitle=Index Page Navigation +commontask_indexinfotext=This link takes you back ot the home page from where you can navigate to other examples +commontask_closeButton=close +commontask_tasklaunch=A sample common task window. +commontask_sampletitle=Sample task page + +# +# Resources for the Tree example +# +tree_title=Tree Index +tree_dynamicTree=Dynamic tree example showing event handling +tree_navTree=Client side navigation tree example in a three frame layout +tree_dynamicTreeTitle=Dynamic Tree Example +tree_navTreeTitle=Navigation Tree Example +tree_breadcrumbMouseOver=Back to Tree Example Index +tree_alarmMajorTip=[Alarm:Major] {0} +tree_alarmMinorTip=[Alarm:Minor] {0} +tree_alarmDownTip=[Alarm:Down] {0} +tree_alarmCriticalTip=[Alarm:Critical] {0} +tree_alertSummary=Element Selected +tree_alertDetail=Element named {0} was selected and has a value of {1}. +tree_testCase_label=Select Test Case: +tree_testCase_title=Actions +tree_testCase_reload=Reload Page +tree_testCase_yoke34=Yoke to Node 34 +tree_framesRequired=This page requires frames. Alternatively, one could construct one or more pages to render the information without using frames. +tree_contentsTitle=Node Details +tree_nodeClicked= was selected +tree_contentBreadcrumbToolip=Click to select {0} + +# +# Resources for the progressbar example +# +progressbar_title=ProgressBar Example +progressbar_example=ProgressBar Example Index +progressbar_exampleIndex=ProgressBar Example Index +progressbar_determinateText=Determinate ProgressBar +progressbar_busyText=Busy ProgressBar +progressbar_indeterminateText=Indeterminate ProgressBar +progressbar_description=Analyzing Host Barney +progressbar_pauseButton=Pause +progressbar_resumeButton=Resume +progressbar_cancelButton=Cancel +progressbar_toolTip_determinate=Determinate ProgressBar +progressbar_toolTip_indeterminate=Indeterminate ProgressBar +progressbar_toolTip_busy=Busy ProgressBar +progressbar_determinate=Determinate ProgressBar +progressbar_indeterminate=Indeterminate ProgressBar +progressbar_busy=Busy ProgressBar +progressbar_pausedText=Task Paused +progressbar_canceledText=Task Canceled +progressbar_completedText=Task Completed Successfully +progressbar_percentText=% complete +progressbar_backButton=Back +# +# Resources for the wizard examples +# +wiz_index_title=Pop-Up Wizard Window Example +wiz_index_popup1_desc=Example 1: This example uses a simple multi-step wizard to create a new user identity. +wiz_index_button1=Wizard Example 1 +wiz_index_button1_tip=Create a new user with a simple wizard. +wiz_simple_title=Example of a Simple Wizard +wiz_user_title=Create a New User Account +wiz_simple_step1_summary=Enter identity and description +wiz_simple_step1_title=User Identity +wiz_simple_step1_detail=Enter new user name, description, and identifier. +wiz_simple_step1_help=User name must be alphanumeric and begin with a letter. User identifier can be generated automatically or set to a number greater than 100. +wiz_user_username=User name: +wiz_user_userdesc=User desc: +wiz_user_uidChoiceText=User identity: +wiz_user_uidAutoGenerate=Auto generate +wiz_user_uidSet=Set explicitly +wiz_user_uid=User uid: +wiz_simple_step2_summary=Enter password information +wiz_simple_step2_title=User Password +wiz_simple_step2_detail=Enter new user password information. +wiz_simple_step2_help=Determine how the user password is set. A password must be from 8 to 32 characters long consisting of alphabetical characters, numbers, and allowable special characters. It must contain at least one upper-case, one lower-case, one numeric, and one of the special characters: ?!()[] +wiz_user_pswdChoiceText=Password option: +wiz_user_pswdLocked=Lock account +wiz_user_pswdFirstLogin=First login +wiz_user_pswdNow=Set now +wiz_user_pswdEnter1=Enter password: +wiz_user_pswdEnter2=Confirm password: +wiz_user_passwordSetting=Password setting: +wiz_simple_step3_summary=Enter user group information +wiz_simple_step3_title=User Groups +wiz_simple_step3_detail=Add new user to existing groups. +wiz_simple_step3_help=Set the primary group for the new user, and optionally add the user to one or more secondary groups. +wiz_user_primaryGroup=Primary group: +wiz_user_secondaryGroup=Secondary groups: +wiz_user_secGroupAvailable=Available groups: +wiz_user_secGroupSelected=Selected groups: +wiz_simple_step4_summary=Enter home directory information +wiz_simple_step4_title=User Home Directory +wiz_simple_step4_detail=Set home directory path for the new user. +wiz_simple_step4_help=Set the home directory server and directory path for the new user. The server name must be a hostname on the network. The directory path must be a fully qualified path. +wiz_user_homeserver=Server name: +wiz_user_homedir=Directory path: +wiz_user_homepath=Home directory: +wiz_simple_step5_summary=Confirm user information +wiz_simple_step5_title=Confirm Values +wiz_simple_step5_detail=Confirm that all values are correct before proceeding. +wiz_simple_step5_help=Confirm each user value before proceeding. If a value is invalid, backup through the steps to reset that value. +wiz_simple_step6_summary=Result of adding new user +wiz_simple_step6_title=Results +wiz_simple_step6_detail=Result of adding new user +wiz_simple_step6_help=Shows the result of the operation for adding a new user. +wiz_simple_result=The user \"{0}\" was added successfully. +wiz_invalid_username_1=User name must begin with a lower case letter. +wiz_invalid_username_2=User name must be from 6 to 32 characters long. +wiz_invalid_username_3=User name contains non-alphabetic, non-numeric, or upper case character. +wiz_invalid_username_4=User name must begin with a lower-case alphabetic character. +wiz_invalid_userid_1=User identity UID is not a numeric value. +wiz_invalid_userid_2=User identity UID must be > 100 and < 65536. +wiz_missing_password=A password must be specified. +wiz_invalid_password_1=User password must be from 8 to 32 characters long. +wiz_invalid_password_2=User password must contain only alphabetic, numeric, or special characters. +wiz_invalid_password_3=User password must contain at least one lower case alphabetic character. +wiz_invalid_password_4=User password must contain at least one upper case alphabetic character. +wiz_invalid_password_5=User password must contain at least one numeric digit. +wiz_invalid_password_6=User password must contain at least one of the special characters \"{0}\". +wiz_missing_confirm=The password value must be confirmed. +wiz_invalid_confirm=User password confirmation is not the same password. +wiz_invalid_servername=Server name is an unknown host. +wiz_invalid_pathname=Home directory path is invalid. +wiz_inhelp_username=Enter 8 to 32 lower-case alphanumeric characters. +wiz_inhelp_useruid=Enter number from 100 to 65535. +wiz_inhelp_password=Enter 8 to 32 alphanumeric and special characters. +wiz_inhelp_confirm=Enter password again for confirmation. +wiz_inhelp_servername=Enter server host name. diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/statictext/Employee.java b/samples/woodstock/src/com/sun/webui/jsf/example/statictext/Employee.java new file mode 100644 index 0000000..bbf45b5 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/statictext/Employee.java @@ -0,0 +1,74 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.statictext; + +import java.beans.*; +import java.io.Serializable; + +/** + * Employee Class + */ +public class Employee implements Serializable { + + // Holds employee details + private String firstName; + private String lastName; + private String designation; + + /** Creates an instance of Employee. */ + public Employee(String firstName, String lastName, String designation) { + this.firstName = firstName; + this.lastName = lastName; + this.designation = designation; + } + + /** Getter for property firstName. */ + public String getFirstName() { + return this.firstName; + } + + /** Setter for property firstName. */ + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + /** Getter for property lastName. */ + public String getLastName() { + return this.lastName; + } + + /** Setter for property lastName. */ + public void setLastName(String lastName) { + this.lastName = lastName; + } + + /** Getter for property designation. */ + public String getDesignation() { + return this.designation; + } + + /** Setter for property designation. */ + public void setDesignation(String designation) { + this.designation = designation; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/statictext/EmployeeConverter.java b/samples/woodstock/src/com/sun/webui/jsf/example/statictext/EmployeeConverter.java new file mode 100644 index 0000000..654babd --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/statictext/EmployeeConverter.java @@ -0,0 +1,74 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.statictext; + +import java.beans.*; +import javax.faces.convert.Converter; +import javax.faces.convert.ConverterException; +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.application.FacesMessage; + +import com.sun.webui.jsf.example.common.MessageUtil; + +/** + * Employee Converter Class + */ +public class EmployeeConverter implements Converter { + + /** Creates an instance of EmployeeConverter. */ + public EmployeeConverter() { + } + + /** Converts an object into a string */ + public String getAsString(FacesContext context, + UIComponent component, + Object value) throws ConverterException { + if (value instanceof Employee) { + StringBuffer strbuf = new StringBuffer(); + strbuf.append(((Employee)value).getFirstName()); + strbuf.append(" "); + strbuf.append(((Employee)value).getLastName()); + strbuf.append("-"); + strbuf.append(((Employee)value).getDesignation()); + return strbuf.toString(); + } + throw new ConverterException(MessageUtil.getMessage("statictext_errorMessage1") + value.toString()); + } + + /** Converts a string into an object */ + public Object getAsObject(FacesContext context, + UIComponent component, + String value) throws ConverterException { + try { + String[] names = value.split(" "); + Employee emp = new Employee(names[0], names[1], names[2]); + return emp; + } + catch (Exception ex) { + String message = MessageUtil.getMessage("statictext_errorMessage2"); + throw new ConverterException(new FacesMessage(message)); + } + + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/statictext/StatictextBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/statictext/StatictextBackingBean.java new file mode 100644 index 0000000..57664b8 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/statictext/StatictextBackingBean.java @@ -0,0 +1,83 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.statictext; + +import java.beans.*; +import java.util.Date; +import java.io.Serializable; + +import com.sun.webui.jsf.example.common.MessageUtil; +import javax.faces.convert.Converter; + +/** + * Backing bean for Static Text example. + */ + +public class StatictextBackingBean implements Serializable { + + // Holds the Date. + Date date = null; + + // Holds the Employee object. + Employee emp = null; + + // Converter for the Employee object. + EmployeeConverter empConverter = new EmployeeConverter(); + + /** Creates a new instance of StatictextBackingBean. */ + public StatictextBackingBean() { + date = new Date(); + emp = new Employee(MessageUtil.getMessage("statictext_firstname"), + MessageUtil.getMessage("statictext_lastname"), + MessageUtil.getMessage("statictext_designation")); + } + + /** Returns the date. */ + public Date getDate() { + return date; + } + + /** Sets the date. */ + public void setDate(Date date) { + this.date = date; + } + + /** Returns employee object. */ + public Employee getEmp() { + return emp; + } + + /** Sets employee object. */ + public void setEmp(Employee emp) { + this.emp = emp; + } + + /** + * Get the converter. + * + * @return converter for the Employee object. + */ + public Converter getEmpConverter() { + return empConverter; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/DynamicGroupTableBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/DynamicGroupTableBean.java new file mode 100644 index 0000000..9619c25 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/DynamicGroupTableBean.java @@ -0,0 +1,120 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table; + +import java.io.Serializable; + +import com.sun.webui.jsf.example.table.util.Dynamic; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +import com.sun.webui.jsf.component.StaticText; +import com.sun.webui.jsf.component.Table; +import com.sun.webui.jsf.component.TableRowGroup; + +/** Backing bean for dynamic group table examples. + * + * Note: To simplify the example, this bean is used only to create the table + * layout. The resulting table will use methods already defined in TableBean. + * + * Note that we must implement java.io.Serializable or + * javax.faces.component.StateHolder in case client-side + * state saving is used, or if server-side state saving is + * used with a distributed system. + */ +public class DynamicGroupTableBean implements Serializable { + private Dynamic dynamic = null; // Dynamic util. + private Table table = null; // Table component. + + // Default constructor. + public DynamicGroupTableBean() { + dynamic = new Dynamic(); + } + + // Get Table component. + public Table getTable() { + if (table == null) { + // Get table row group. + TableRowGroup rowGroup1 = dynamic.getTableRowGroup("rowGroup1", + "#{TableBean.groupB.names}", + "#{TableBean.groupB.select.selectedState}", + "Group Header"); + TableRowGroup rowGroup2 = dynamic.getTableRowGroup("rowGroup2", + "#{TableBean.groupC.names}", + "#{TableBean.groupC.select.selectedState}", + "Group Header"); + + // Set table row group properties. + dynamic.setTableRowGroupChildren(rowGroup1, + "#{TableBean.groupB.select.selectedState}", + "#{TableBean.groupB.select.selected}", + "#{TableBean.groupB.select.selectedValue}", null, true); + dynamic.setTableRowGroupChildren(rowGroup2, + "#{TableBean.groupC.select.selectedState}", + "#{TableBean.groupC.select.selected}", + "#{TableBean.groupC.select.selectedValue}", null, false); + + // Set select and row group toggle buttons. + rowGroup1.setSelectMultipleToggleButton(true); + rowGroup2.setSelectMultipleToggleButton(true); + rowGroup1.setGroupToggleButton(true); + rowGroup2.setGroupToggleButton(true); + + // Get table. + table = dynamic.getTable("table1", null); + table.getChildren().add(rowGroup1); + table.getChildren().add(rowGroup2); + + // Add title facet. + StaticText title = new StaticText(); + title.setText(MessageUtil.getMessage("table_dynamicGroupTitle")); + table.getFacets().put(Table.TITLE_FACET, title); + } + return table; + } + + // Set Table component. + // + // @param table The Table component. + public void setTable(Table table) { + this.table = table; + } + + // Action handler when navigating to the table index. + public String showTableIndex() { + reset(); + return TableBean.SHOW_TABLE_INDEX; + } + + // Action handler when navigating to the main example index. + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + // Reset values so next visit starts fresh. + private void reset() { + table = null; + dynamic = new Dynamic(); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/DynamicTableBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/DynamicTableBean.java new file mode 100644 index 0000000..090433c --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/DynamicTableBean.java @@ -0,0 +1,99 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table; + +import java.io.Serializable; + +import com.sun.webui.jsf.component.Table; +import com.sun.webui.jsf.component.TableRowGroup; + +import com.sun.webui.jsf.example.table.util.Dynamic; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +/** Backing bean for dynamic table examples. + * + * Note: To simplify the example, this bean is used only to create the table + * layout. The resulting table will use methods already defined in TableBean. + * + * Note that we must implement java.io.Serializable or + * javax.faces.component.StateHolder in case client-side + * state saving is used, or if server-side state saving is + * used with a distributed system. + */ +public class DynamicTableBean implements Serializable { + private Dynamic dynamic = null; // Dynamic util. + private Table table = null; // Table component. + + // Default constructor. + public DynamicTableBean() { + dynamic = new Dynamic(); + } + + // Get Table component. + public Table getTable() { + if (table == null) { + // Get table row group. + TableRowGroup rowGroup1 = dynamic.getTableRowGroup("rowGroup1", + "#{TableBean.groupB.names}", + "#{TableBean.groupB.select.selectedState}", null); + + // Set table row group properties. + dynamic.setTableRowGroupChildren(rowGroup1, + "#{TableBean.groupB.select.selectedState}", + "#{TableBean.groupB.select.selected}", + "#{TableBean.groupB.select.selectedValue}", + "#{TableBean.groupB.actions.action}", true); + + // Get table. + table = dynamic.getTable("table1", MessageUtil.getMessage("table_dynamicTitle")); + table.getChildren().add(rowGroup1); + } + return table; + } + + // Set Table component. + // + // @param table The Table component. + public void setTable(Table table) { + this.table = table; + } + + // Action handler when navigating to the table index. + public String showTableIndex() { + reset(); + return TableBean.SHOW_TABLE_INDEX; + } + + // Action handler when navigating to the main example index. + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + // Reset values so next visit starts fresh. + private void reset() { + table = null; + dynamic = new Dynamic(); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/TableBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/TableBean.java new file mode 100644 index 0000000..fe0bd98 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/TableBean.java @@ -0,0 +1,176 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table; + +import java.io.Serializable; +import java.util.ArrayList; + +import com.sun.webui.jsf.component.Alarm; + +import com.sun.webui.jsf.example.table.util.Group; +import com.sun.webui.jsf.example.table.util.Name; +import com.sun.webui.jsf.example.index.IndexBackingBean; + +/** + * Backing bean for table examples. + * + * Note that we must implement java.io.Serializable or + * javax.faces.component.StateHolder in case client-side + * state saving is used, or if server-side state saving is + * used with a distributed system. + */ +public class TableBean implements Serializable { + + // Navigation case outcome to go to table index + public static final String SHOW_TABLE_INDEX = "showTableIndex"; + + // Group util for table examples. + private Group groupA = null; // List (rows 0-19). + private Group groupB = null; // Array (rows 0-9). + private Group groupC = null; // Array (rows 10-19). + private Group groupD = null; // List (rows 0-19)-- Used for hidden selected rows. + + // Alarms. + private static final Alarm down = new Alarm(Alarm.SEVERITY_DOWN); + private static final Alarm critical = new Alarm(Alarm.SEVERITY_CRITICAL); + private static final Alarm major = new Alarm(Alarm.SEVERITY_MAJOR); + private static final Alarm minor = new Alarm(Alarm.SEVERITY_MINOR); + private static final Alarm ok = new Alarm(Alarm.SEVERITY_OK); + + // Data for table examples. + protected static final Name[] names = { + new Name("William", "Dupont", down, + "Hot", "Purple", "Yellow", "In Service"), + new Name("Anna", "Keeney", critical, + "Non-recoverable error", "Red", "Pink", "Brown"), + new Name("Mariko", "Randor", major, + "Cold", "Degraded", "Green", "-"), + new Name("John", "Wilson", minor, + "Warm", "Blue", "Power mode", "Xray"), + new Name("Lynn", "Seckinger", ok, + "Cool", "-", "Black", "Ok"), + new Name("Richard", "Tattersall", down, + "Lukewarm", "Aqua", "-", "Starting"), + new Name("Gabriella", "Sarintia", critical, + "Stopped", "Jesmui", "One", "-"), + new Name("Lisa", "Hartwig", major, + "Coolant leak", "Stressed", "Bandaid applied", "-"), + new Name("Shirley", "Jones", minor, + "Orange", "Two", "In service", "Shields are raised"), + new Name("Bill", "Sprague", ok, + "-", "Three", "Tastes great", "Ok"), + new Name("Greg", "Doench", down, + "Less filling", "Four", "-", "Stopping"), + new Name("Solange", "Nadeau", critical, + "-", "Five", "Not responding", "No contact"), + new Name("Heather", "McGann", major, + "Bud", "Predictive failure", "-", "-"), + new Name("Roy", "Martin", minor, + "Coors", "Six", "Slow", "abcdef"), + new Name("Claude", "Loubier", ok, + "Sam Adams", "Seven", "-", "Ok"), + new Name("Dan", "Woodard", down, + "Heineken", "Bud Lite", "-", "Stopping"), + new Name("Ron", "Dunlap", critical, + "Dormant", "Eight", "-", "-"), + new Name("Keith", "Frankart", major, + "Miller", "Degraded", "Twelve", "-"), + new Name("Andre", "Nadeau", minor, + "Nine", "Eleven", "In service", "Foster Lager"), + new Name("Horace", "Celestin", ok, + "Ten", "Molson", "-", "Ok"), + }; + + // Default constructor. + public TableBean() { + } + + // Get Group util created with a List containing all names. + public Group getGroupA() { + if (groupA != null) { + return groupA; + } + // Create List with all names. + ArrayList newNames = new ArrayList(); + for (int i = names.length - 1; i >= 0; i--) { + newNames.add(names[i]); + } + return (groupA = new Group(newNames)); + } + + // Get Group util created with an array containing a subset of names. + public Group getGroupB() { + if (groupB != null) { + return groupB; + } + // Create an array with subset of names (i.e., 0-9). + Name[] newNames = new Name[10]; + System.arraycopy(names, 0, newNames, 0, 10); + return (groupB = new Group(newNames)); + } + + // Get Group util created with an array containing a subset of names. + public Group getGroupC() { + if (groupC != null) { + return groupC; + } + // Create an array with subset of names (i.e., 10-19). + Name[] newNames = new Name[10]; + System.arraycopy(names, 10, newNames, 0, 10); + return (groupC = new Group(newNames)); + } + + // Get Group util created with a List containing all names and a + // flag to indicate that selection state is maintained arcoss pages. + public Group getGroupD() { + if (groupD != null) { + return groupD; + } + // Create List with all names. + ArrayList newNames = new ArrayList(); + for (int i = names.length - 1; i >= 0; i--) { + newNames.add(names[i]); + } + return (groupD = new Group(newNames, true)); + } + + // Action handler when navigating to the table index. + public String showTableIndex() { + reset(); + return SHOW_TABLE_INDEX; + } + + // Action handler when navigating to the main example index. + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + // Reset values so next visit starts fresh. + private void reset() { + groupA = null; + groupB = null; + groupC = null; + groupD = null; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Actions.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Actions.java new file mode 100644 index 0000000..1836a7a --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Actions.java @@ -0,0 +1,149 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; + +import com.sun.data.provider.FieldKey; +import com.sun.data.provider.RowKey; +import com.sun.data.provider.TableDataProvider; +import com.sun.data.provider.impl.ObjectListDataProvider; +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.model.OptionTitle; + +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import com.sun.webui.jsf.example.common.MessageUtil; + +// This class provides functionality for table actions. +public class Actions { + private Group group = null; // Group util. + + // Action menu items. + protected static final Option[] moreActionsOptions = { + new OptionTitle(MessageUtil.getMessage("table_ActionsMenuTitle")), + new Option("ACTION1", MessageUtil.getMessage("table_Action1")), + new Option("ACTION2", MessageUtil.getMessage("table_Action2")), + new Option("ACTION3", MessageUtil.getMessage("table_Action3")), + new Option("ACTION4", MessageUtil.getMessage("table_Action4")), + }; + + // Default constructor. + public Actions(Group group) { + this.group = group; + } + + // Action button event. + public void action() { + String message = null; + + // Get hyperlink parameter used for embedded actions example. + Map map = FacesContext.getCurrentInstance().getExternalContext() + .getRequestParameterMap(); + String param = (String) map.get("param"); + if (param != null) { + message = MessageUtil.getMessage("table_embeddedActionMsg") + " " + param; + } else { + message = MessageUtil.getMessage("table_tableActionMsg"); + } + + group.getMessages().setMessage(message); + } + + // Action to remove rows from ObjectListDataProvider. + public void delete() { + // Since mutiple examples are using the same beans, the binding + // simply tells us that checkbox state is maintained arcoss pages. + if (group.getSelect().isKeepSelected()) { + // If we got here, then we're maintaining state across pages. + delete(group.getTableRowGroup().getSelectedRowKeys()); + } else { + // If we got here, then we're using the phase listener and must + // take filtering, sorting, and pagination into account. + delete(group.getTableRowGroup().getRenderedSelectedRowKeys()); + } + } + + // Set disabled value for table actions. + public boolean getDisabled() { + // If there is at least one row selection, actions are enabled. + boolean result = true; + if (group.getTableRowGroup() == null) { + return result; + } + + // Since mutiple examples are using the same beans, the binding + // simply tells us that checkbox state is maintained arcoss pages. + if (group.getSelect().isKeepSelected()) { + // If we got here, then we're maintaining state across pages. + result = group.getTableRowGroup().getSelectedRowsCount() < 1; + } else { + // If we got here, then we're using the phase listener and must + // take filtering, sorting, and pagination into account. + result = group.getTableRowGroup().getRenderedSelectedRowsCount() < 1; + } + return result; + } + + // Get action. + public String getMoreActions() { + // Per the UI guidelines, always snap back to "More Actions...". + return OptionTitle.NONESELECTED; + } + + // Get action menu options. + public Option[] getMoreActionsOptions() { + return moreActionsOptions; + } + + // Action menu event. + public void moreActions() { + group.getMessages().setMessage(MessageUtil.getMessage("table_moreActionsMsg")); + } + + // Set action. + public void setMoreActions(String action) { + // Do nothing. + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Action to remove rows from ObjectListDataProvider. + private void delete(RowKey[] rowKeys) { + if (rowKeys == null) { + return; + } + TableDataProvider provider = group.getNames(); + for (int i = 0; i < rowKeys.length; i++) { + RowKey rowKey = rowKeys[i]; + if (provider.canRemoveRow(rowKey)) { + provider.removeRow(rowKey); + } + } + ((ObjectListDataProvider) provider).commitChanges(); // Commit. + group.getSelect().clear(); // Clear phase listener. + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Dynamic.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Dynamic.java new file mode 100644 index 0000000..e2740d2 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Dynamic.java @@ -0,0 +1,217 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; +import com.sun.webui.jsf.example.util.ExampleUtilities; + +import com.sun.webui.jsf.component.Checkbox; +import com.sun.webui.jsf.component.Hyperlink; +import com.sun.webui.jsf.component.StaticText; +import com.sun.webui.jsf.component.Table; +import com.sun.webui.jsf.component.TableColumn; +import com.sun.webui.jsf.component.TableRowGroup; + +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.component.UIParameter; + +// This class provides functionality for dynamic tables. +public class Dynamic { + public static final String CHECKBOX_ID = "select"; + public static final String HYPERLINK_ID = "link"; + + // Default constructor. + public Dynamic() { + } + + // Note: When using tags in a JSP page, UIComponentTag automatically creates + // a unique id for the component. However, when dynamically creating + // components, via a backing bean, the id has not been set. In this + // scenario, allowing JSF to create unique Ids may cause problems with + // Javascript and components may not be able to maintain state properly. + // For example, if a component was assigned "_id6" as an id, that means + // there were 5 other components that also have auto-generated ids. Let us + // assume one of those components was a complex component that, as part of + // its processing, adds an additional non-id'd child before redisplaying the + // view. Now, the id of this component will be "_id7" instead of "_id6". + // Assigning your own id ensures that conflicts do not occur. + + // Get Table component. + // + // @param id The component id. + // @param title The table title text. + public Table getTable(String id, String title) { + // Get table. + Table table = new Table(); + table.setDeselectMultipleButton(true); // Show deselect multiple button. + table.setSelectMultipleButton(true); // Show select multiple button. + table.setTitle(title); // Set title text. + + return table; + } + + // Get TableRowGroup component with header. + // + // @param id The component id. + // @param sourceData Value binding expression for model data. + // @param selected Value binding expression for selected property. + // @param header Value binding expression for row group header text. + public TableRowGroup getTableRowGroup(String id, String sourceData, + String selected, String header) { + // Get table row group. + TableRowGroup rowGroup = new TableRowGroup(); + rowGroup.setId(id); // Set id. + rowGroup.setSourceVar("name"); // Set source var. + rowGroup.setHeaderText(header); // Set header text. + ExampleUtilities.setValueExpression(rowGroup, + "selected", selected); // Set row highlight. + ExampleUtilities.setValueExpression(rowGroup, + "sourceData", sourceData); // Set source data. + + return rowGroup; + } + + // Get TableColumn component. + // + // @param id The component id. + // @param sort Value binding expression for column sort. + // @param align The field key for column alignment. + // @param header The column header text. + // @param selectId The component id used to select table rows. + public TableColumn getTableColumn(String id, String sort, String align, + String header, String selectId) { + // Get table column. + TableColumn col = new TableColumn(); + col.setId(id); // Set id. + col.setSelectId(selectId); // Set id used to select table rows. + col.setHeaderText(header); // Set header text. + col.setAlignKey(align); // Set align key. + ExampleUtilities.setValueExpression(col, "sort", sort); // Set sort. + + return col; + } + + // Get Checkbox component used for select column. + // + // @param id The component id. + // @param selected Value binding expression for selected property. + // @param selectedValue Value binding expression for selectedValue property. + public Checkbox getCheckbox(String id, String selected, + String selectedValue) { + // Get checkbox. + Checkbox cb = new Checkbox(); + cb.setId(id); // Set id here and set row highlighting below. + cb.setOnClick("setTimeout('initAllRows()', 0)"); + ExampleUtilities.setValueExpression(cb, + "selected", selected); // Set selected. + ExampleUtilities.setValueExpression(cb, + "selectedValue", selectedValue); // Set selected value. + + return cb; + } + + // Get Hyperlink component. + // + // @param id The component id. + // @param text Value binding expression for text. + // @param action Method binding expression for action. + // @param parameter Value binding expression for parameter. + public Hyperlink getHyperlink(String id, String text, String action, + String parameter) { + // Get hyperlink. + Hyperlink hyperlink = new Hyperlink(); + hyperlink.setId(id); // Set id. + ExampleUtilities.setValueExpression(hyperlink, + "text", text); // Set text. + ExampleUtilities.setMethodExpression(hyperlink, + "actionExpression", action); // Set action. + + // Create paramerter. + UIParameter param = new UIParameter(); + param.setId(id + "_param"); + param.setName("param"); + ExampleUtilities.setValueExpression(param, + "value", parameter); // Set parameter. + hyperlink.getChildren().add(param); + + return hyperlink; + } + + // Get StaticText component. + // + // @param text Value binding expression for text. + public StaticText getText(String text) { + // Get static text. + StaticText staticText = new StaticText(); + ExampleUtilities.setValueExpression(staticText, + "text", text); // Set text. + + return staticText; + } + + // Set TableRowGroup children. + // + // @param rowGroup The TableRowGroup component. + // @param cbSort Value binding expression for cb sort. + // @param cbSelected Value binding expression for cb selected property. + // @param cbSelectedValue Value binding expression for cb selectedValue property. + // @param action The Method binding expression for hyperlink action. + // @param showHeader Flag indicating to display column header text. + public void setTableRowGroupChildren(TableRowGroup rowGroup, String cbSort, + String cbSelected, String cbSelectedValue, String action, + boolean showHeader) { + // UI guidelines recomend no headers for second row group. + String header1 = showHeader ? "Last Name" : null; + String header2 = showHeader ? "First Name" : null; + + // Get columns. + TableColumn col1 = getTableColumn( + "col0", cbSort, null, null, CHECKBOX_ID); + TableColumn col2 = getTableColumn( + "col1", "#{name.value.last}", "last", header1, null); + TableColumn col3 = getTableColumn( + "col2", "#{name.value.first}", "first", header2, null); + + // Get column components. + Checkbox cb = getCheckbox(CHECKBOX_ID, cbSelected, cbSelectedValue); + StaticText firstName = getText("#{name.value.first}"); + + // If action was provided, add a hyperlink; otherwise, use static text. + if (action != null) { + Hyperlink lastName = getHyperlink(HYPERLINK_ID, + "#{name.value.last}", action, + "#{name.value.last}"); + col2.getChildren().add(lastName); + } else { + StaticText lastName = getText("#{name.value.last}"); + col2.getChildren().add(lastName); + } + + // Add Children. + col1.getChildren().add(cb); + col3.getChildren().add(firstName); + rowGroup.getChildren().add(col1); + rowGroup.getChildren().add(col2); + rowGroup.getChildren().add(col3); + } + +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Filter.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Filter.java new file mode 100644 index 0000000..2bedf9d --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Filter.java @@ -0,0 +1,155 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; + +import com.sun.data.provider.FilterCriteria; +import com.sun.data.provider.impl.CompareFilterCriteria; +import com.sun.webui.jsf.component.Table; +import com.sun.webui.jsf.model.Option; + +import com.sun.webui.jsf.example.common.MessageUtil; + +// This class provides functionality for table filters. +// +// This util class sets filters directly on the TableRowGroup component using +// FilterCriteria; however, there is also a FilteredTableDataProvider class that +// can used for filtering outside of the table. The table will pick up what ever +// filter has been applied automatically, for example: +// +// // Some choice of TableDataProvider. +// TableDataProvider provider = new ... +// +// // This wraps and filters an existing TableDataProvider. +// FilteredTableDataProvider filteredProvider = new FilteredTableDataProvider(); +// filteredProvider.setTableDataProvider(provider); +// +// // Set FilteredTableDataProvider in the TableRowGroup component. +// tableRowGroup.setSourceData(filteredProvider); +// +// The table component itself has no idea that there is any filtering going on, +// but the filtering functionality has been encapsulated in the data provider. +// The developer can then use different FilterCriteria types to apply filters, +// for example: +// +// CompareFilterCriteria cfc = new ... +// RegexFilterCriteria rxfc = new ... +// filteredProvider.setFilterCriteria(new FilterCriteria[] { cfc, fxfc }); +public class Filter { + private String customFilter = null; // Custom filter. + private String basicFilter = null; // Basic filter menu option. + private String filterText = null; // Filter text. + private Group group = null; // Group util. + + // Filter menu items. + protected static final Option[] filterOptions = { + new Option("FILTER0", MessageUtil.getMessage("table_filterAllItems")), + new Option("FILTER1", MessageUtil.getMessage("table_filter1")), + new Option("FILTER2", MessageUtil.getMessage("table_filter2")), + }; + + // Default constructor. + public Filter(Group group) { + this.group = group; + } + + // UI guidelines state that a "Custom Filter" option should be added to the + // filter menu, used to open the table filter panel. Thus, if the + // CUSTOM_FILTER option is selected, Javascript invoked via the onChange + // event will open the table filter panel. + // + // UI guidelines also state that a "Custom Filter Applied" option should be + // added to the filter menu, indicating that a custom filter has been + // applied. In this scenario, set the selected property of the filter menu + // as CUSTOM_FILTER_APPLIED. This selection should persist until another + // menu option has been selected. + // + // Further, UI guidelines state that the table title should indicate that a + // custom filter has been applied. To add this text to the table title, set + // the filter property. + + // Basic filter event. + public void applyBasicFilter() { + if (basicFilter.equals("FILTER1")) { + filterText = MessageUtil.getMessage("table_filter1"); + } else if (basicFilter.equals("FILTER2")) { + filterText = MessageUtil.getMessage("table_filter2"); + } else { + filterText = null; + } + + // Clear all filters since we don't have an example here. + // + // Note: TableRowGroup ensures pagination is reset per UI guidelines. + group.getTableRowGroup().setFilterCriteria(null); + } + + // Custom filter event. + public void applyCustomFilter() { + basicFilter = Table.CUSTOM_FILTER_APPLIED; // Set filter menu option. + filterText = MessageUtil.getMessage("table_filterCustom"); + + // Filter rows that do not match custom filter. + CompareFilterCriteria criteria = new CompareFilterCriteria( + group.getNames().getFieldKey("last"), customFilter); + + // Note: TableRowGroup ensures pagination is reset per UI guidelines. + group.getTableRowGroup().setFilterCriteria( + new FilterCriteria[] {criteria}); + } + + // Get basic filter. + public String getBasicFilter() { + // Note: the selected value must be set to restore the default selected + // value when the embedded filter panel is closed. Further, the selected + // value should never be set as "Custom Filter...". + return (basicFilter != null && !basicFilter.equals(Table.CUSTOM_FILTER)) + ? basicFilter : "FILTER0"; + } + + // Set basic filter. + public void setBasicFilter(String value) { + basicFilter = value; + } + + // Get custom filter. + public String getCustomFilter() { + return customFilter; + } + + // Set custom filter. + public void setCustomFilter(String value) { + customFilter = value; + } + + // Get filter menu options. + public Option[] getFilterOptions() { + // Get filter options based on the selected filter menu option. + return Table.getFilterOptions(filterOptions, + basicFilter == Table.CUSTOM_FILTER_APPLIED); + } + + // Get filter text. + public String getFilterText() { + return filterText; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Group.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Group.java new file mode 100644 index 0000000..031e7cf --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Group.java @@ -0,0 +1,125 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; + +import com.sun.data.provider.TableDataProvider; +import com.sun.data.provider.impl.ObjectArrayDataProvider; +import com.sun.data.provider.impl.ObjectListDataProvider; +import com.sun.webui.jsf.component.Checkbox; +import com.sun.webui.jsf.component.TableRowGroup; + +import java.util.List; + +// This class contains data provider and util classes. Note that not all util +// classes are used for each example. +public class Group { + private TableRowGroup tableRowGroup = null; // TableRowGroup component. + private TableDataProvider provider = null; // Data provider. + private Checkbox checkbox = null; // Checkbox component. + private Preferences prefs = null; // Preferences util. + private Messages messages = null; // Messages util. + private Actions actions = null; // Actions util. + private Filter filter = null; // Filter util. + private Select select = null; // Select util. + + // Default constructor. + public Group() { + actions = new Actions(this); + filter = new Filter(this); + select = new Select(this); + prefs = new Preferences(); + messages = new Messages(); + } + + // Construct an instance using given Object array. + public Group(Object[] array) { + this(); + provider = new ObjectArrayDataProvider(array); + } + + // Construct an instance using given List. + public Group(List list) { + this(); + provider = new ObjectListDataProvider(list); + } + + // Construct an instance using given List and a + // flag indicating that selected objects should + // not be cleared after the render response phase. + public Group(List list, boolean keepSelected) { + actions = new Actions(this); + select = new Select(this, keepSelected); + messages = new Messages(); + provider = new ObjectListDataProvider(list); + } + + // Get data provider. + public TableDataProvider getNames() { + return provider; + } + + // Get Actions util. + public Actions getActions() { + return actions; + } + + // Get Filter util. + public Filter getFilter() { + return filter; + } + + // Get Messages util. + public Messages getMessages() { + return messages; + } + + // Get Preferences util. + public Preferences getPreferences() { + return prefs; + } + + // Get Select util. + public Select getSelect() { + return select; + } + + // Get tableRowGroup component. + public TableRowGroup getTableRowGroup() { + return tableRowGroup; + } + + // Set tableRowGroup component. + public void setTableRowGroup(TableRowGroup tableRowGroup) { + this.tableRowGroup = tableRowGroup; + } + + // Get checkbox component. + public Checkbox getCheckbox() { + return checkbox; + } + + // Set checkbox component. + public void setCheckbox(Checkbox checkbox) { + this.checkbox = checkbox; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Messages.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Messages.java new file mode 100644 index 0000000..f182214 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Messages.java @@ -0,0 +1,41 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; + +public class Messages { + private String message = null; // JSF messages. + + // Default constructor. + public Messages() { + } + + // Get message. + public String getMessage() { + return message; + } + + // Set message. + public void setMessage(String message) { + this.message = message; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Name.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Name.java new file mode 100644 index 0000000..09b3acd --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Name.java @@ -0,0 +1,138 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; + +import com.sun.webui.jsf.component.Alarm; +import com.sun.webui.jsf.theme.ThemeImages; + +public class Name { + private String last = null; // Last name. + private String first = null; // First name. + private Alarm alarm = null; // Alarm. + private String statusA = null; // A status + private String statusB = null; // B status + private String statusC = null; // C status + private String statusD = null; // D status + + // Default constructor. + public Name(String first, String last) { + this.last = last; + this.first = first; + } + + // Construct an instance with given alarm severity. + public Name(String first, String last, Alarm alarm) { + this(first, last); + this.alarm = alarm; + } + + // Construct an instance with given alarm severity and statuses. + public Name(String first, String last, Alarm alarm, + String statusA, String statusB, String statusC, String statusD) { + this(first, last, alarm); + this.statusA = statusA; + this.statusB = statusB; + this.statusC = statusC; + this.statusD = statusD; + } + + // Get first name. + public String getFirst() { + return first; + } + + // Set first name. + public void setFirst(String first) { + this.first = first; + } + + // Get last name. + public String getLast() { + return last; + } + + // Set last name. + public void setLast(String last) { + this.last = last; + } + + // Get alarm. + public Alarm getAlarm() { + return alarm; + } + + // Get alarm. + public void setAlarm(Alarm alarm) { + this.alarm = alarm; + } + + // Get status A + public String getStatusA() { + return statusA; + } + + // Set status A + public void setStatusA(String status) { + this.statusA = status; + } + + // Get status B + public String getStatusB() { + return statusB; + } + + // Set status B + public void setStatusB(String status) { + this.statusB = status; + } + + // Get status C + public String getStatusC() { + return statusC; + } + + // Set status C + public void setStatusC(String status) { + this.statusC = status; + } + + // Get status D + public String getStatusD() { + return statusD; + } + + // Set status D + public void setStatusD(String status) { + this.statusD = status; + } + + // Get alarm severity. + public String getSeverity() { + return alarm.getSeverity(); + } + + // Get alarm severity. + public void setSeverity(String severity) { + alarm.setSeverity(severity); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Preferences.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Preferences.java new file mode 100644 index 0000000..241f340 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Preferences.java @@ -0,0 +1,58 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; + +// This class provides functionality for table preferences. +public class Preferences { + private String preference = null; // Rows preference. + private int rows = 5; // Rows per page. + + // Default constructor. + public Preferences() { + } + + // Table preferences event. + public void applyPreferences() { + try { + int rows = Integer.parseInt(preference); + if (rows > 0) { + this.rows = rows; + } + } catch (NumberFormatException e) {} + } + + // Get rows per page. + public int getRows() { + return rows; + } + + // Get preference. + public String getPreference() { + return Integer.toString(rows); + } + + // Set preference. + public void setPreference(String value) { + preference = value; + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Select.java b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Select.java new file mode 100644 index 0000000..36934b1 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/table/util/Select.java @@ -0,0 +1,120 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.table.util; + +import com.sun.webui.jsf.example.util.ExampleUtilities; + +import com.sun.data.provider.FieldKey; +import com.sun.data.provider.RowKey; +import com.sun.data.provider.TableDataProvider; +import com.sun.webui.jsf.event.TableSelectPhaseListener; + +import javax.faces.context.FacesContext; +import javax.el.ValueExpression; + +// This class provides functionality for select tables. +// +// Note: UI guidelines recomend that rows should be unselected when no longer in +// view. For example, when a user selects rows of the table and navigates to +// another page. Or, when a user applies a filter or sort that may hide +// previously selected rows from view. If a user invokes an action to delete +// the currently selected rows, they may inadvertently remove rows not +// displayed on the current page. Using TableSelectPhaseListener ensures +// that invalid row selections are not rendered by clearing selected state +// after the render response phase. +public class Select { + private TableSelectPhaseListener tspl = null; // Phase listener. + private Group group = null; // Group util. + + // Default constructor. + public Select(Group group) { + this.group = group; + tspl = new TableSelectPhaseListener(); + } + + // Construct an instance. The given flag indicates that selected + // objects should not be cleared after the render response phase. + public Select(Group group, boolean keepSelected) { + this.group = group; + tspl = new TableSelectPhaseListener(keepSelected); + } + + // Clear selected state from phase listener (e.g., when deleting rows). + public void clear() { + tspl.clear(); + } + + // Test flag indicating that selected objects should not be cleared. + public boolean isKeepSelected() { + return tspl.isKeepSelected(); + } + + // Set flag indicating that selected objects should not be cleared. + public void keepSelected(boolean keepSelected) { + tspl.keepSelected(keepSelected); + } + + // Get selected property. + public Object getSelected() { + return tspl.getSelected(getTableRow()); + } + + // Set selected property. + public void setSelected(Object object) { + RowKey rowKey = getTableRow(); + if (rowKey != null) { + tspl.setSelected(rowKey, object); + } + } + + // Get selected value property. + public Object getSelectedValue() { + RowKey rowKey = getTableRow(); + return (rowKey != null) ? rowKey.getRowId() : null; + } + + // Get the selected state -- Sort on checked state only. + public boolean getSelectedState() { + // Typically, selected state is tested by comparing the selected and + // selectedValue properties. In this example, however, the phase + // listener value is not null when selected. + return getSelectedState(getTableRow()); + } + + // Get the selected state. + public boolean getSelectedState(RowKey rowKey) { + return tspl.isSelected(rowKey); + } + + // Get current table row. + // + // Note: To obtain a RowKey for the current table row, the use the same + // sourceVar property given to the TableRowGroup component. For example, if + // sourceVar="name", use "#{name.tableRow}" as the expression string. + private RowKey getTableRow() { + FacesContext context = FacesContext.getCurrentInstance(); + ValueExpression ve = ExampleUtilities.createValueExpression(context, + "#{name.tableRow}", Object.class); + return (RowKey) ve.getValue(context.getELContext()); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/tree/DynamicTreeBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/tree/DynamicTreeBackingBean.java new file mode 100644 index 0000000..db28674 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/tree/DynamicTreeBackingBean.java @@ -0,0 +1,417 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.tree; + +import java.io.Serializable; +import javax.faces.event.ActionEvent; +import javax.faces.component.UIComponentBase; + +import com.sun.webui.jsf.example.index.IndexBackingBean; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.util.ExampleUtilities; + +import com.sun.webui.jsf.component.Tree; +import com.sun.webui.jsf.component.TreeNode; +import com.sun.webui.jsf.component.Hyperlink; +import com.sun.webui.jsf.component.ImageHyperlink; +import com.sun.webui.jsf.component.ImageComponent; +import com.sun.webui.jsf.theme.ThemeImages; +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.model.OptionTitle; +import com.sun.webui.jsf.component.DropDown; + +/** + * Backing bean for Dynamic Tree example. + */ +public class DynamicTreeBackingBean implements Serializable { + + // Outcome strings used in the faces config. + public final static String SHOW_DYNAMIC_TREE = "showDynamicTree"; + public final static String SHOW_TREE_INDEX = "showTreeIndex"; + + // Constants for tree node images. For all leaf nodes that require + // a badging of the alarm severity with the document images, we had to + // create our own images which are loaded from within the app's + // context. For all others we simply create mappings to the names + // of the themed icons. + // + public final static String TREE_DOCUMENT_ALARM_MAJOR = + "/images/tree_document_major.gif"; + public final static String TREE_DOCUMENT_ALARM_MINOR = + "/images/tree_document_minor.gif"; + public final static String TREE_DOCUMENT_ALARM_DOWN = + "/images/tree_document_down.gif"; + public final static String TREE_DOCUMENT_ALARM_CRITICAL = + "/images/tree_document_critial.gif"; + public final static String TREE_DOCUMENT = + ThemeImages.TREE_DOCUMENT; + public final static String TREE_FOLDER = + ThemeImages.TREE_FOLDER; + public final static String TREE_FOLDER_ALARM_MAJOR = + ThemeImages.TREE_FOLDER_ALARM_MAJOR; + public final static String TREE_FOLDER_ALARM_MINOR = + ThemeImages.TREE_FOLDER_ALARM_MINOR; + public final static String TREE_FOLDER_ALARM_DOWN = + ThemeImages.TREE_FOLDER_ALARM_DOWN; + public final static String TREE_FOLDER_ALARM_CRITICAL = + ThemeImages.TREE_FOLDER_ALARM_CRITICAL; + + + private Tree tree = null; + private String alertDetail = null; + private Boolean alertRendered = Boolean.FALSE; + private Option[] testCaseOptions = null; + + + /** Constructor */ + public DynamicTreeBackingBean() { + testCaseOptions = new Option[3]; + testCaseOptions[0] = new OptionTitle( + MessageUtil.getMessage("tree_testCase_title")); + testCaseOptions[1] = new Option("tree_testCase_reload", + MessageUtil.getMessage("tree_testCase_reload")); + testCaseOptions[2] = new Option("tree_testCase_yoke34", + MessageUtil.getMessage("tree_testCase_yoke34")); + } + + /** Get the Tree object */ + public Tree getTree() { + if (tree != null) + return tree; + + // Create root of tree + tree = new Tree(); + tree.setId("DynamicTree"); + tree.setText("Node 0"); + + // At this time, the root node is not selectable. Until it is, + // we do not create a facet for the content, but only for the image + // via an ImageComponent - that is, it's not a link. + boolean rootNodeSelectable = false; + if (rootNodeSelectable) { + tree.getFacets().put("content", + nodeLink(tree.getText(), 0)); + tree.getFacets().put("image", + nodeImage(tree.getText(), 0, TREE_FOLDER_ALARM_DOWN)); + } else { + ImageComponent imageComponent = new ImageComponent(); + imageComponent.setId(nodeImageID(0)); + tree.getFacets().put("image", imageComponent); + setNodeImage(tree, TREE_FOLDER_ALARM_DOWN); + } + makeToolTip(tree, TREE_FOLDER_ALARM_DOWN); + + // Create a series of 2nd-level child nodes, and a couple of 3rd-level + // grand-child nodes. + for (int i = 10; i < 51; i += 10) { + TreeNode n, c; + + // 2nd-level child node + n = addTreeNode(tree, "Node " + i, i, TREE_FOLDER); + + // 3rd-level grandchild nodes + c = addTreeNode(n, "Node " + (i + 1), (i + 1), TREE_DOCUMENT); + c = addTreeNode(n, "Node " + (i + 2), (i + 2), TREE_DOCUMENT); + } + + // Create more 3rd-level grandchild nodes but with at least one + // showing a major alarm. + TreeNode node30 = tree.getChildNode(treeNodeID(30)); + if (node30 != null) { + TreeNode node31 = node30.getChildNode(treeNodeID(31)); + if (node31 != null) { + addTreeNode(node31, "Node 33", 33, TREE_DOCUMENT); + addTreeNode(node31, "Node 34", 34, TREE_DOCUMENT_ALARM_MAJOR); + + // Propogate the alarm condition up the ancestry chain. + setNodeImage(node31, TREE_FOLDER_ALARM_MAJOR); + setNodeImage(node30, TREE_FOLDER_ALARM_MAJOR); + } + } + + // Create more 3rd-level grandchild nodes but with at least one + // showing a down alarm. + TreeNode node50 = tree.getChildNode(treeNodeID(50)); + if (node50 != null) { + TreeNode node52 = node50.getChildNode(treeNodeID(52)); + if (node52 != null) { + addTreeNode(node52, "Node 53", 53, TREE_DOCUMENT); + addTreeNode(node52, "Node 54", 54, TREE_FOLDER_ALARM_DOWN); + + // Propogate the alarm condition up the ancestry chain. + setNodeImage(node52, TREE_FOLDER_ALARM_DOWN); + setNodeImage(node50, TREE_FOLDER_ALARM_DOWN); + } + } + + // Set a minor alarm on an existing leaf node and propogate up + // the ancestry chain. + TreeNode node40 = tree.getChildNode(treeNodeID(40)); + if (node40 != null) { + TreeNode node42 = node40.getChildNode(treeNodeID(42)); + if (node42 != null) { + setNodeImage(node42, TREE_FOLDER_ALARM_MINOR); + setNodeImage(node40, TREE_FOLDER_ALARM_MINOR); + } + } + + return tree; + } + + /** Set the Tree Object */ + public void setTree(Tree tree) { + this.tree = tree; + } + + public String getAlertDetail() { + return alertDetail; + } + + public String getAlertRendered() { + return alertRendered.toString(); + } + + /** Return the array of test case options */ + public Option[] getTestCaseOptions() { + return testCaseOptions; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Handlers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action handler when navigating to the dynamic tree example */ + public String showDynamicTree() { + return SHOW_DYNAMIC_TREE; + } + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + /** Action handler when navigating to the tree example index. */ + public String showTreeIndex() { + reset(); + return SHOW_TREE_INDEX; + } + + /** Action handler when clicking on a tree node */ + public String treeNodeAction() { + return null; + } + + /** Action listener when clicking on a tree node */ + public void treeNodeActionListener(ActionEvent ae) { + String componentID = ((UIComponentBase)ae.getSource()).getId(); + String nodeNum; + try { + nodeNum = Integer.toString(getNodeNum(componentID)); + } catch (Exception e) { + nodeNum = componentID; + } + Object[] args = { tree.getId(), nodeNum }; + alertDetail = MessageUtil.getMessage("tree_alertDetail", args); + alertRendered = Boolean.TRUE; + tree.setSelected(componentID); + } + + /** Action handler for the testcase dropdown menu */ + public String testCaseAction() { + alertDetail = null; + alertRendered = Boolean.FALSE; + return null; + } + + /** Action listener for the testcase dropdown menu */ + public void testCaseActionListener(ActionEvent ae) { + // Get the selection from the dropdown + DropDown dropDown = (DropDown) ae.getComponent(); + String selected = (String) dropDown.getSelected(); + + if (selected.equals("tree_testCase_yoke34")) { + // Make sure node 34 exists. + String id = treeNodeID(34); + TreeNode node = tree.getChildNode(id); + if (node != null) { + // It exists, so select it and expand all ancester nodes + tree.setSelected(id); + TreeNode parent = TreeNode.getParentTreeNode(node); + while (parent != null) { + parent.setExpanded(true); + parent = TreeNode.getParentTreeNode(parent); + } + } + } + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Reset everything back to initial state */ + private void reset() { + alertDetail = null; + alertRendered = Boolean.FALSE; + tree = null; + } + + private TreeNode addTreeNode(TreeNode parent, String label, + int nodeNum, String icon) { + + TreeNode node = new TreeNode(); + node.setText(label); + node.setId(treeNodeID(nodeNum)); + node.getFacets().put("image", nodeImage(label, nodeNum, icon)); + node.getFacets().put("content", nodeLink(label, nodeNum)); + makeToolTip(node, icon); + + parent.getChildren().add(node); + return node; + } + + /** Return a Hyperlink object */ + private Hyperlink nodeLink(String label, int nodeNum) { + Hyperlink link = new Hyperlink(); + link.setId(nodeLinkID(nodeNum)); + link.setText(label); + ExampleUtilities.setMethodExpression(link, + "actionExpression", "#{DynamicTreeBean.treeNodeAction}"); + + Class[] paramTypes = new Class[] {ActionEvent.class}; + ExampleUtilities.setMethodExpression(link, + "actionListenerExpression", "#{DynamicTreeBean.treeNodeActionListener}", + null, paramTypes); + + return link; + } + + /** Return an ImageHyperlink object */ + private ImageHyperlink nodeImage(String label, int nodeNum, String icon) { + ImageHyperlink link = new ImageHyperlink(); + link.setId(nodeImageID(nodeNum)); + _setNodeImage(link, icon); + ExampleUtilities.setMethodExpression(link, + "actionExpression", "#{DynamicTreeBean.treeNodeAction}"); + + Class[] paramTypes = new Class[] {ActionEvent.class}; + ExampleUtilities.setMethodExpression(link, + "actionListenerExpression", "#{DynamicTreeBean.treeNodeActionListener}", + null, paramTypes); + + return link; + } + + /** Set the image for a specified tree node */ + private void setNodeImage(TreeNode node, String icon) { + _setNodeImage((Object)(node.getFacets().get("image")), icon); + makeToolTip(node, icon); + } + + /** Set the image for a specified image component. */ + private void _setNodeImage(Object o, String icon) { + if (o == null) + return; + + // For themed images, we call setIcon on the ImageHyperLink. + // Otherwise we call setImageURL. + if (icon.equals(TREE_DOCUMENT) + || icon.equals(TREE_FOLDER) + || icon.equals(TREE_FOLDER_ALARM_MINOR) + || icon.equals(TREE_FOLDER_ALARM_MAJOR) + || icon.equals(TREE_FOLDER_ALARM_DOWN) + || icon.equals(TREE_FOLDER_ALARM_CRITICAL) ) { + if (o instanceof ImageHyperlink) + ((ImageHyperlink)o).setIcon(icon); + if (o instanceof ImageComponent) + ((ImageComponent)o).setIcon(icon); + } else { + if (o instanceof ImageHyperlink) + ((ImageHyperlink)o).setImageURL(icon); + if (o instanceof ImageComponent) + ((ImageComponent)o).setUrl(icon); + } + } + + /** Compose the tooltip and set it on all facets of the node */ + private void makeToolTip(TreeNode node, String icon) { + String tip = node.getText(); + if (icon.equals(TREE_FOLDER_ALARM_MINOR)) + tip = MessageUtil.getMessage("tree_alarmMinorTip", tip); + else if (icon.equals(TREE_FOLDER_ALARM_MAJOR)) + tip = MessageUtil.getMessage("tree_alarmMajorTip", tip); + else if (icon.equals(TREE_FOLDER_ALARM_DOWN)) + tip = MessageUtil.getMessage("tree_alarmDownTip", tip); + else if (icon.equals(TREE_FOLDER_ALARM_CRITICAL)) + tip = MessageUtil.getMessage("tree_alarmCriticalTip", tip); + else if (icon.equals(TREE_DOCUMENT_ALARM_MINOR)) + tip = MessageUtil.getMessage("tree_alarmMinorTip", tip); + else if (icon.equals(TREE_DOCUMENT_ALARM_MAJOR)) + tip = MessageUtil.getMessage("tree_alarmMajorTip", tip); + else if (icon.equals(TREE_DOCUMENT_ALARM_DOWN)) + tip = MessageUtil.getMessage("tree_alarmDownTip", tip); + else if (icon.equals(TREE_DOCUMENT_ALARM_CRITICAL)) + tip = MessageUtil.getMessage("tree_alarmCriticalTip", tip); + + Object o = (Object)(node.getFacets().get("image")); + if (o instanceof ImageHyperlink) + ((ImageHyperlink)o).setToolTip(tip); + if (o instanceof ImageComponent) + ((ImageComponent)o).setToolTip(tip); + + o = (Object)(node.getFacets().get("content")); + if (o instanceof Hyperlink) + ((Hyperlink)o).setToolTip(tip); + else + node.setToolTip(tip); + } + + // Because we're identifying node with an integer, and JSF requires + // IDs to be start with a letter or underscore, we provide convenience + // methods for creating unique IDs from an integer. + + /** Return a valid component ID for a treeNode */ + private String treeNodeID(int nodeNum) { + return "Node" + nodeNum; + } + + /** Return a valid component ID for a treenode's content facet */ + private String nodeLinkID(int nodeNum) { + return treeNodeID(nodeNum) + "Link"; + } + + /** Return a valid component ID for a treenode's image facet */ + private String nodeImageID(int nodeNum) { + return treeNodeID(nodeNum) + "Image"; + } + + /** Extract and return the node number from the specified component ID */ + private int getNodeNum(String id) { + String nodeNum = id; + nodeNum = nodeNum.replace("Node", ""); + nodeNum = nodeNum.replace("Image", ""); + nodeNum = nodeNum.replace("Link", ""); + return Integer.parseInt(nodeNum); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/tree/NavTreeBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/tree/NavTreeBackingBean.java new file mode 100644 index 0000000..cab511a --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/tree/NavTreeBackingBean.java @@ -0,0 +1,395 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.tree; + +import java.io.Serializable; +import java.util.ArrayList; + +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.component.UIComponentBase; + +import com.sun.webui.jsf.example.index.IndexBackingBean; +import com.sun.webui.jsf.example.common.MessageUtil; +import com.sun.webui.jsf.example.common.ClientSniffer; +import com.sun.webui.jsf.example.util.ExampleUtilities; + +import com.sun.webui.jsf.component.Tree; +import com.sun.webui.jsf.component.TreeNode; +import com.sun.webui.jsf.component.Hyperlink; +import com.sun.webui.jsf.component.ImageHyperlink; +import com.sun.webui.jsf.component.ImageComponent; +import com.sun.webui.jsf.theme.ThemeImages; + +/** + * Backing bean for Dynamic Tree example. + */ +public class NavTreeBackingBean implements Serializable { + + // Outcome strings used in the faces config. + public final static String SHOW_NAV_TREE = "showNavTree"; + public final static String SHOW_TREE_INDEX = "showTreeIndex"; + + private ClientSniffer cs; + + public final static String TREE_DOCUMENT = ThemeImages.TREE_DOCUMENT; + public final static String TREE_FOLDER = ThemeImages.TREE_FOLDER; + + private Tree tree = null; + private int nodeClicked = 0; + private Boolean breadcrumbsRendered = Boolean.FALSE; + + // Due to a bug, the root node is not selectable. + private final static boolean ROOTNODESELECTABLE = false; + + /** Default constructor */ + public NavTreeBackingBean() { + FacesContext context = FacesContext.getCurrentInstance(); + cs = new ClientSniffer(context); + } + + /** Get the Tree object */ + public Tree getTree() { + if (tree != null) + return tree; + + // Create root of tree + tree = new Tree(); + tree.setId("navtree"); + tree.setText("Node 0"); + tree.setClientSide(true); + + // Until root node is selectable, we do not create a facet for + // the content, but only for the image via an ImageComponent - + // that is, it's not a link. + if (ROOTNODESELECTABLE) { + tree.getFacets().put("content", + nodeLink(tree.getText(), 0)); + tree.getFacets().put("image", + nodeImage(tree.getText(), 0, TREE_FOLDER)); + } else { + ImageComponent imageComponent = new ImageComponent(); + imageComponent.setId(nodeImageID(0)); + tree.getFacets().put("image", imageComponent); + setNodeImage(tree, TREE_FOLDER); + } + makeToolTip(tree, TREE_FOLDER); + + // Create a series of 2nd-level child nodes, and a couple of 3rd-level + // grand-child nodes. + for (int i = 10; i < 21; i += 10) { + TreeNode n, c; + + // 2nd-level child node + n = addTreeNode(tree, "Node " + i, i, TREE_FOLDER); + + // 3rd-level grandchild nodes + c = addTreeNode(n, "Node " + (i + 1), (i + 1), TREE_DOCUMENT); + c = addTreeNode(n, "Node " + (i + 2), (i + 2), TREE_DOCUMENT); + } + + // Create a 2nd-level folder child of node10, and then create some + // 3rd-level grand-child nodes. + TreeNode node10 = tree.getChildNode(treeNodeID(10)); + if (node10 != null) { + TreeNode node30 = addTreeNode(node10, "Node 30", 30, TREE_FOLDER); + addTreeNode(node30, "Node 31", 31, TREE_DOCUMENT); + addTreeNode(node30, "Node 32", 32, TREE_DOCUMENT); + addTreeNode(node30, "Node 33", 33, TREE_DOCUMENT); + } + + return tree; + } + + /** Set the Tree Object */ + public void setTree(Tree tree) { + this.tree = tree; + } + + /** + * Get the 'rows' attribute value for the outer frameset based on the + * client browser. + */ + public String getOuterFramesetRows() { + if (cs.isIe6up()) { + return "68,*"; + } + + // assume default is Mozilla-based + return "75,*"; + } + + /** Return the node number of the tree node that was clicked */ + public String getNodeClicked() { + String param = (String) FacesContext.getCurrentInstance(). + getExternalContext().getRequestParameterMap(). + get("nodeClicked"); + try { + nodeClicked = Integer.parseInt(param); + } catch (Exception e) { + nodeClicked = 0; + return "Nothing"; + } + + return Integer.toString(nodeClicked); + } + + /** Return the rendered status of the breadbrumbs */ + public String getBreadcrumbsRendered() { + getNodeClicked(); + if (nodeClicked == 0) + breadcrumbsRendered = Boolean.FALSE; + else + breadcrumbsRendered = Boolean.TRUE; + return breadcrumbsRendered.toString(); + } + + /** Return the parentage path for the currently selected node */ + public Hyperlink[] getPageList() { + + // No path needed if not rendering breadcrumbs + getBreadcrumbsRendered(); + if (breadcrumbsRendered == Boolean.FALSE) + return null; + + // No path needed for the root node + if (nodeClicked == 0) + return null; + + // Get the node object of the selected node, + // with usual protection from Murphy's Law! + TreeNode node = tree.getChildNode(treeNodeID(nodeClicked)); + if (node == null) + return null; + + // Build up an array ancestry nodes starting with the selection + ArrayList ancestry = new ArrayList(); + ancestry.add(node); + TreeNode parent = TreeNode.getParentTreeNode(node); + while (parent != null) { + ancestry.add(parent); + parent = TreeNode.getParentTreeNode(parent); + } + + // Create the breadcrumbs for the ancestry, in the reverse + // order of the node array list. + Hyperlink[] pages = new Hyperlink[ancestry.size()]; + int n = 0; + for (int i = ancestry.size() - 1; i >= 0; i--) { + node = (TreeNode) ancestry.get(i); + Hyperlink link = new Hyperlink(); + + // Breadcrumb link text same as node's content facet if it + // exists, otherwise from the node. + Hyperlink facet = (Hyperlink) node.getFacets().get("content"); + if (facet != null) + link.setText(facet.getText()); + else + link.setText(node.getText()); + + // Config what happens when this link is clicked + link.setTarget("contentsFrame"); + try { + String toolTip = MessageUtil.getMessage( + "tree_contentBreadcrumbToolip", + (String) link.getText()); + + // Re-render the contents frame to show which node is selected. + int nodeNum = getNodeNum(node); + if (!ROOTNODESELECTABLE && (nodeNum == 0)) { + link.setUrl("content.jsf"); + toolTip += " (root node currently not selectable)"; + } + else + link.setUrl("content.jsf?nodeClicked=" + nodeNum); + + link.setToolTip(toolTip); + link.setId(breadcrumbLinkID(nodeNum)); + + // Yoke to this node in the tree. + FacesContext context = FacesContext.getCurrentInstance(); + String clientID = node.getClientId(context); + if (!ROOTNODESELECTABLE && (nodeNum == 0)) + link.setOnClick("javascript:ClearHighlight(); return true;"); + else + link.setOnClick("javascript:YokeToNode('" + clientID + + "'); return true;"); + } catch (Exception e) { + } + + pages[n++] = link; + } + + return pages; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Action Handlers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Action handler when navigating to the navigation tree example */ + public String showNavTree() { + return SHOW_NAV_TREE; + } + + /** Action handler when navigating to the main example index. */ + public String showExampleIndex() { + reset(); + return IndexBackingBean.INDEX_ACTION; + } + + /** Action handler when navigating to the tree example index. */ + public String showTreeIndex() { + reset(); + return SHOW_TREE_INDEX; + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Private methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Reset everything back to initial state */ + private void reset() { + nodeClicked = 0; + breadcrumbsRendered = Boolean.FALSE; + tree = null; + } + + /** Create a new tree node child of a specified parent node */ + private TreeNode addTreeNode(TreeNode parent, String label, + int nodeNum, String icon) { + + TreeNode node = new TreeNode(); + node.setText(label); + node.setId(treeNodeID(nodeNum)); + node.getFacets().put("image", nodeImage(label, nodeNum, icon)); + node.getFacets().put("content", nodeLink(label, nodeNum)); + makeToolTip(node, icon); + + parent.getChildren().add(node); + return node; + } + + /** Return a Hyperlink object */ + private Hyperlink nodeLink(String label, int nodeNum) { + Hyperlink link = new Hyperlink(); + link.setId(nodeLinkID(nodeNum)); + link.setText(label); + link.setTarget("contentsFrame"); + link.setUrl("content.jsf?nodeClicked=" + nodeNum); + return link; + } + + /** Return an ImageHyperlink object */ + private ImageHyperlink nodeImage(String label, int nodeNum, String icon) { + ImageHyperlink link = new ImageHyperlink(); + link.setId(nodeImageID(nodeNum)); + _setNodeImage(link, icon); + link.setTarget("contentsFrame"); + link.setUrl("content.jsf?nodeClicked=" + nodeNum); + return link; + } + + /** Set the image for a specified tree node */ + private void setNodeImage(TreeNode node, String icon) { + _setNodeImage((Object)(node.getFacets().get("image")), icon); + makeToolTip(node, icon); + } + + /** Set the image for a specified image component. */ + private void _setNodeImage(Object o, String icon) { + if (o == null) + return; + + if (o instanceof ImageHyperlink) + ((ImageHyperlink)o).setIcon(icon); + if (o instanceof ImageComponent) + ((ImageComponent)o).setIcon(icon); + } + + /** Compose the tooltip and set it on all facets of the node */ + private void makeToolTip(TreeNode node, String icon) { + String tip = node.getText(); + + Object o = (Object)(node.getFacets().get("image")); + if (o instanceof ImageHyperlink) + ((ImageHyperlink)o).setToolTip(tip); + if (o instanceof ImageComponent) + ((ImageComponent)o).setToolTip(tip); + + o = (Object)(node.getFacets().get("content")); + if (o instanceof Hyperlink) + ((Hyperlink)o).setToolTip(tip); + else + node.setToolTip(tip); + } + + // Because we're identifying node with an integer, and JSF requires + // IDs to be start with a letter or underscore, we provide convenience + // methods for creating unique IDs from an integer. + + /** Return a valid component ID for a treeNode */ + private String treeNodeID(int nodeNum) { + return "Node" + nodeNum; + } + + /** Return a valid component ID for a treenode's content facet */ + private String nodeLinkID(int nodeNum) { + return treeNodeID(nodeNum) + "Link"; + } + + /** Return a valid component ID for a treenode's image facet */ + private String nodeImageID(int nodeNum) { + return treeNodeID(nodeNum) + "Image"; + } + + /** Return a valid component ID for a breadcrumb link */ + private String breadcrumbLinkID(int nodeNum) { + return "Breadcrumb" + nodeNum; + } + + /** Extract and return the node number from the specified component ID */ + private int getNodeNum(String id) { + String nodeNum = id; + nodeNum = nodeNum.replace("Node", ""); + nodeNum = nodeNum.replace("Image", ""); + nodeNum = nodeNum.replace("Link", ""); + nodeNum = nodeNum.replace("Breadcrumb", ""); + return Integer.parseInt(nodeNum); + } + + /** Extract and return the node number from the specified TreeNode */ + private int getNodeNum(TreeNode node) { + Object o = (Object)(node.getFacets().get("content")); + if (o instanceof Hyperlink) + return getNodeNum(((Hyperlink)o).getId()); + + o = (Object)(node.getFacets().get("image")); + if (o instanceof ImageHyperlink) + return getNodeNum(((ImageHyperlink)o).getId()); + if (o instanceof ImageComponent) + return getNodeNum(((ImageComponent)o).getId()); + + return getNodeNum(node.getId()); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/util/ExampleUtilities.java b/samples/woodstock/src/com/sun/webui/jsf/example/util/ExampleUtilities.java new file mode 100644 index 0000000..aeac4f3 --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/util/ExampleUtilities.java @@ -0,0 +1,97 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.util; + +import javax.el.MethodExpression; +import javax.el.ValueExpression; +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; + +public class ExampleUtilities { + + protected ExampleUtilities() { + super(); + } + + /** + * Helper method to set value expression property. + * + * @param component The UIComponent to set a value expression for. + * @param name The name of the value expression property. + * @param expression The expresion for the value expression. + */ + public static void setValueExpression(UIComponent component, String name, + String expression) { + if (expression == null) { + return; + } + FacesContext context = FacesContext.getCurrentInstance(); + component.setValueExpression(name, createValueExpression( + context, expression, Object.class)); + } + + /** + * Helper method to set a method expression property. + * Create a method expression that returns String and has no + * input paramaters. + * + * @param component The UIComponent to set a value binding for. + * @param name The name of the method expression property + * @param expression The expression to create. + */ + public static void setMethodExpression(UIComponent component, + String name, String expression) { + setMethodExpression(component, name, expression, + Object.class, new Class[0]); + } + /** + * Helper method to set a method expression property. + * + * @param component The UIComponent to set a value binding for. + * @param name The name of the method expression property + * @param expression The expression to create. + */ + public static void setMethodExpression(UIComponent component, + String name, String expression, Class out, Class[] in) { + if (expression == null) { + return; + } + FacesContext context = FacesContext.getCurrentInstance(); + component.getAttributes().put(name, + createMethodExpression(context, expression, out, in)); + } + + public static MethodExpression createMethodExpression( + FacesContext context, String expr, Class out, Class[] in) { + + return context.getApplication().getExpressionFactory(). + createMethodExpression(context.getELContext(), expr, out, in); + } + + public static ValueExpression createValueExpression( + FacesContext context, String expr, Class value) { + + return context.getApplication().getExpressionFactory(). + createValueExpression(context.getELContext(), expr, value); + } +} diff --git a/samples/woodstock/src/com/sun/webui/jsf/example/wizard/SimpleWizardBackingBean.java b/samples/woodstock/src/com/sun/webui/jsf/example/wizard/SimpleWizardBackingBean.java new file mode 100644 index 0000000..2f35bbe --- /dev/null +++ b/samples/woodstock/src/com/sun/webui/jsf/example/wizard/SimpleWizardBackingBean.java @@ -0,0 +1,775 @@ +/* + * The contents of this file are subject to the terms + * of the Common Development and Distribution License + * (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the license at + * https://woodstock.dev.java.net/public/CDDLv1.0.html. + * See the License for the specific language governing + * permissions and limitations under the License. + * + * When distributing Covered Code, include this CDDL + * Header Notice in each file and include the License file + * at https://woodstock.dev.java.net/public/CDDLv1.0.html. + * If applicable, add the following below the CDDL Header, + * with the fields enclosed by brackets [] replaced by + * you own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + */ + +package com.sun.webui.jsf.example.wizard; + +import java.io.Serializable; +import java.io.File; +import java.net.InetAddress; + +import javax.faces.context.FacesContext; +import javax.faces.component.UIComponent; +import javax.faces.application.FacesMessage; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; + +import com.sun.webui.jsf.component.Wizard; +import com.sun.webui.jsf.component.WizardStep; +import com.sun.webui.jsf.event.WizardEvent; +import com.sun.webui.jsf.event.WizardEventListener; +import com.sun.webui.jsf.model.Option; +import com.sun.webui.jsf.example.index.IndexBackingBean; +import com.sun.webui.jsf.example.common.MessageUtil; + +/** + * Backing bean for Simple Wizard example. + */ +public class SimpleWizardBackingBean implements Serializable { + + // Define constants + private static final String SPECIAL_PSWD_CHARS = "?()[]!"; + private static final String DEFAULT_HOME_PATH = "/export/home/"; + private static final String PASSWORD_SETTING_LOCKED = "Locked"; + private static final String PASSWORD_SETTING_FIRSTLOGIN = "First Login"; + private static final String PASSWORD_SETTING_CREATE = "Create now"; + + // Bean properties. + private String userName = ""; + private String userDesc = ""; + private String userUid = ""; + private boolean uidAutoGenerate = false; + private boolean uidSet = true; + private String userPswd = ""; + private String userPswdConfirm = ""; + private boolean pswdNow = true; + private boolean pswdLocked = false; + private boolean pswdFirstLogin = false; + private String primaryGroupName = "other"; + private String[] secondaryGroupNames = new String[0]; + private String homeServer = ""; + private String homePath = null; + private String resultMessage = "Invalid results!"; + + // Private members + private String checkPswd = null; + + // Data lists used by some wizard steps. + private Option[] primaryGroupList; + private Option[] secondaryGroupList; + + /** + * Constructor initializes some list elements. + */ + public SimpleWizardBackingBean() { + + primaryGroupList = initPrimaryGroupList(); + secondaryGroupList = initSecondaryGroupList(); + + } // Constructor + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Value binding methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** Getter for user name */ + public String getUserName() { + return (userName); + } + + /** Setter for user name */ + public void setUserName(String name) { + userName = name; + } + + /** Getter for user description */ + public String getUserDescription() { + return (userDesc); + } + + /** Setter for user description */ + public void setUserDescription(String desc) { + userDesc = desc; + } + + /** Getter for user uid */ + public String getUserUid() { + return (userUid ); + } + + /** Setter for user uid */ + public void setUserUid(String uid) { + userUid = uid; + } + + /** Getter for uid auto generate radio button */ + public boolean isUidAutoGenerate() { + return(uidAutoGenerate); + } + + /** Setter for uid auto generate radio button */ + public void setUidAutoGenerate(boolean value) { + uidAutoGenerate = value; + if (uidAutoGenerate) { + userUid = generateUserUid(); + } + } + + /** Getter for uid explict set radio button */ + public boolean isUidSet() { + return(uidSet); + } + + /** Setter for uid explict set radio button */ + public void setUidSet(boolean value) { + uidSet = value; + if (uidSet) { + userUid = ""; + } + } + + /** Getter for uid field disabled state */ + public boolean isUidDisabled() { + // UID field is disabled when auto generate is selected. + return (uidAutoGenerate); + } + + /** Setter for uid field disabled state */ + public void setUidDisabled(boolean value) { + // Not explicitly set; derived from radio button settings. + } + + /** Getter for user password */ + public String getUserPassword() { + return (userPswd); + } + + /** Setter for user password */ + public void setUserPassword(String pswd) { + userPswd = pswd; + } + + /** Getter for user password confirmation */ + public String getUserPasswordConfirm() { + return (userPswdConfirm); + } + + /** Setter for user password confirm */ + public void setUserPasswordConfirm(String pswd) { + userPswdConfirm = pswd; + } + + /** Getter for password locked radio button */ + public boolean isPswdLocked() { + return(pswdLocked); + } + + /** Setter for password locked radio button */ + public void setPswdLocked(boolean value) { + pswdLocked = value; + } + + /** Getter for password on first login radio button */ + public boolean isPswdFirstLogin() { + return(pswdFirstLogin); + } + + /** Setter for password on first login radio button */ + public void setPswdFirstLogin(boolean value) { + pswdFirstLogin = value; + } + + /** Getter for password now radio button */ + public boolean isPswdNow() { + return(pswdNow); + } + + /** Setter for password now radio button */ + public void setPswdNow(boolean value) { + pswdNow = value; + // If set now is not selected, clear password fields. + if (! pswdNow) { + userPswd = ""; + userPswdConfirm = ""; + } + } + + /** Getter for password field disabled state */ + public boolean isPasswordDisabled() { + // Password is disabled if Set Now is not enabled. + return (! pswdNow); + } + + /** Setter for password field disabled state */ + public void setPasswordDisabled(boolean value) { + // Not explicitly set; derived from radio button settings. + } + + /** Getter for password confirmation field disabled state */ + public boolean isPasswordConfirmDisabled() { + // Confirmation is disabled if Set Now is not enabled. + return (! pswdNow); + } + + /** Setter for password confirmation field disabled state */ + public void setPasswordConfirmDisabled(boolean value) { + // Not explicitly set; derived from radio button settings. + } + + /** Getter for primary group name */ + public String getPrimaryGroupName() { + return (primaryGroupName); + } + + /** Setter for primary group name */ + public void setPrimaryGroupName(String groupName) { + primaryGroupName = groupName; + } + + /** Getter for home directory server */ + public String getHomeServer() { + return (homeServer); + } + + /** Setter for home directory server */ + public void setHomeServer(String serverName) { + homeServer = serverName; + } + + /** Getter for home directory path */ + public String getHomePath() { + String val = homePath; + if ((val == null) || (val.length() == 0)) { + val = DEFAULT_HOME_PATH; + if (userName != null) { + val = val + userName; + } + } + return (val); + } + + /** Setter for home directory path */ + public void setHomePath(String pathName) { + homePath = pathName; + } + + /** Getter for home directory server and path */ + public String getHomeDirectory() { + return (homeServer + ":" + homePath); + } + + /** Getter for primary group drop down list */ + public Option[] getPrimaryGroupList() { + return (primaryGroupList); + } + + /** Getter for selected secondary group names */ + public String[] getSecondaryGroupNames() { + if (secondaryGroupNames == null) { + return (new String[0]); + } else { + return (secondaryGroupNames); + } + } + + /** Setter for selected secondary group names */ + public void setSecondaryGroupNames(String[] groupNames) { + secondaryGroupNames = groupNames; + } + + /** Getter for secondary group available list */ + public Option[] getSecondaryGroupList() { + return (secondaryGroupList); + } + + /** Getter for password setting option */ + public String getPasswordSetting() { + String val = ""; + if (pswdLocked) { + val = PASSWORD_SETTING_LOCKED; + } else if (pswdFirstLogin) { + val = PASSWORD_SETTING_FIRSTLOGIN; + } else if (pswdNow) { + val = PASSWORD_SETTING_CREATE; + } + return (val); + } + + /** Setter for password setting option */ + public void setPasswordSetting() { + // Not set, but derived from radio settings. + } + + /** Getter for results of operation */ + public String getResultMessage() { + return (resultMessage); + } + + /** Setter for results of operation */ + public void setResultMessage(String msg) { + resultMessage = msg; + } + + /** Getter for wizard event handler */ + public WizardEventListener getWizardEventListener() { + return (new SimpleWizardEventListener(this)); + } + + /** Getter for wizard step event handler */ + public WizardEventListener getWizardStepEventListener() { + return (new SimpleWizardEventListener(this)); + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Validator methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Validator for user name. Name must be a string of ASCII + * characters from 6 to 32 bytes long comprised of lower case letters + * and numbers, and beginning with a letter. + * + * @throws ValidatorException + */ + public void validateUserName(FacesContext context, + UIComponent component, Object value) throws ValidatorException { + + if (value != null) { + boolean bValid = false; + String user = value.toString(); + char[] cs = user.toCharArray(); + String msgKey = "wiz_invalid_username_1"; + if (Character.isLowerCase(cs[0])) { + // Check for a valid user name length. + msgKey = "wiz_invalid_username_2"; + if ((cs.length > 5) && (cs.length < 33)) { + // Check for valid characters in the name. + bValid = true; + for (int i = 0; i < cs.length; i++) { + if ((Character.isLowerCase(cs[i])) || + (Character.isDigit(cs[i]))) { + continue; + } + msgKey = "wiz_invalid_username_3"; + bValid = false; + break; + } // End of for + if (bValid) { + // Check first character is valid. + if (! Character.isLowerCase(cs[0])) { + msgKey = "wiz_invalid_username_4"; + bValid = false; + } + } + } + } + if (! bValid) { + String msgString = + MessageUtil.getMessage(msgKey); + FacesMessage msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + } + + } // validateUserName + + /** + * Validator for user uid. Name must be an integer number + * from 100 to 65535. We should check if the UID is already + * in use, but this is not part of this example. + * + * @throws ValidatorException + */ + public void validateUserUid(FacesContext context, + UIComponent component, Object value) + throws ValidatorException { + + int uid = -1; + boolean bValid = false; + if (value != null) { + String msgKey = ""; + try { + uid = (new Integer ((String) value)).intValue(); + msgKey = "wiz_invalid_userid_2"; + if ((uid >= 100) & (uid < 65536)) { + bValid = true; + } + } catch (Exception ex) { + // Number format error + msgKey = "wiz_invalid_userid_1"; + } + if (! bValid) { + String msgString = + MessageUtil.getMessage(msgKey); + FacesMessage msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + } + + } // validateUserUid + + /** + * Validator for user password. Must be an ASCII string + * at least 8 bytes long consisting of lower case and + * upper case alphabetic characters, numbers, and some + * specific punctuation marks. + * + * @throws ValidatorException + */ + public void validateUserPassword(FacesContext context, + UIComponent component, Object value) + throws ValidatorException { + + // We only validate the password if the option to + // set it now was selected. Note that a value must + // be specified for the password field in this case. + if (! pswdNow) { + return; + } + checkPswd=null; + String pswd = null; + boolean bValid = false; + String msgKey = "wiz_missing_password"; + if (value != null) { + pswd = value.toString(); + char[] cs = pswd.toCharArray(); + // Check for proper password length. + msgKey = "wiz_invalid_password_1"; + if ((cs.length > 7) && (cs.length < 33)) { + boolean bUpper = false; + boolean bLower = false; + boolean bDigit = false; + boolean bSpecial = false; + // Check for an invalid character. + bValid = true; + for (int i = 0; i < cs.length; i++) { + int iUpper = 0; + int iLower = 0; + int iDigit = 0; + int iSpecial = 0; + if (Character.isLowerCase(cs[i])) { + bLower = true; + iLower = 1; + } + if (Character.isUpperCase(cs[i])) { + bUpper = true; + iUpper = 1; + } + if (Character.isDigit(cs[i])) { + bDigit = true; + iDigit = 1; + } + if (SPECIAL_PSWD_CHARS.indexOf(cs[i]) >= 0) { + bSpecial = true; + iSpecial = 1; + } + if ((iLower + iUpper + iDigit + iSpecial) == 0) { + msgKey = "wiz_invalid_password_2"; + bValid = false; + break; + } + } // End of for + // Check that we have at least one character from + // each category. + if (bValid) { + if (! bLower) { + msgKey = "wiz_invalid_password_3"; + bValid = false; + } else if (! bUpper) { + msgKey = "wiz_invalid_password_4"; + bValid = false; + } else if (! bDigit) { + msgKey = "wiz_invalid_password_5"; + bValid = false; + } else if (! bSpecial) { + msgKey = "wiz_invalid_password_6"; + bValid = false; + } + } + } + } + if (! bValid) { + String msgString = MessageUtil.getMessage(msgKey, + SPECIAL_PSWD_CHARS); + FacesMessage msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + checkPswd = pswd; + + } // validateUserPassword + + /** + * Validator for confirming user password. Assumes it is + * called after the first password validator above. Checks + * that the confirmation value equals the original password + * value. + * + * @throws ValidatorException + */ + public void confirmUserPassword(FacesContext context, + UIComponent component, Object value) + throws ValidatorException { + + // We only confirm the password if the option to set a + // password now was selected. If checking, the password + // field validator left us the password value. + if (! pswdNow) { + return; + } + boolean bValid = true; + String msgKey = ""; + if (value != null) { + String pswd = value.toString(); + if (checkPswd != null) { + if (! checkPswd.equals(pswd)) { + msgKey = "wiz_invalid_confirm"; + bValid = false; + } + } + } else { + msgKey = "wiz_missing_confirm"; + bValid = false; + } + checkPswd = null; + if (! bValid) { + String msgString = MessageUtil.getMessage(msgKey); + FacesMessage msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + + } // confirmUserPassword + + /** + * Validator for home directory server. Must be a host + * accessible from this server. + * + * @throws ValidatorException + */ + public void validateHomeServer(FacesContext context, + UIComponent component, Object value) + throws ValidatorException { + + String host = null; + boolean bValid = false; + if (value != null) { + try { + host = (String) value; + InetAddress.getByName(host); + bValid = true; + } catch (Exception ex) { + // Unknown host error + } + if (! bValid) { + String msgString = + MessageUtil.getMessage("wiz_invalid_servername"); + FacesMessage msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + } + + } // validateHomeServer + + /** + * Validator for home directory path. Must be a fully + * qualified path name. We should check that the directory + * exists as a shared file system path on the home directory + * server, but that is not part of this example. + * + * @throws ValidatorException + */ + public void validateHomePath(FacesContext context, + UIComponent component, Object value) + throws ValidatorException { + + String path = null; + boolean bValid = false; + if (value != null) { + try { + path = (String) value; + if ((path.length() > 0) && + (! path.equals(DEFAULT_HOME_PATH))) { + File fPath = new File(path); + if (fPath.isAbsolute()) { + bValid = true; + } + } + } catch (Exception ex) { + // Class cast error + } + if (! bValid) { + String msgString = + MessageUtil.getMessage("wiz_invalid_pathname"); + FacesMessage msg = new FacesMessage(msgString); + msg.setSeverity(FacesMessage.SEVERITY_ERROR); + throw new ValidatorException(msg); + } + } + + } // validateHomePath + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Initialize methods + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Set auto generated user identifier. + // Probably OS specific, but we just fake it for our example. + private String generateUserUid() { + + long t = System.currentTimeMillis(); + int uid = (int) (t - ((t/1000)*1000)) + 100; + return (Integer.toString(uid)); + + } // generateUserUid + + // Generate the list of primary group names. + // Typically accessed from underlying OS. + private Option[] initPrimaryGroupList() { + + Option[] list = new Option[6]; + list[0] = new Option("staff", "staff"); + list[1] = new Option("engineering", "engineering"); + list[2] = new Option("marketing", "marketing"); + list[3] = new Option("sysadmin", "sysadmin"); + list[4] = new Option("other", "other"); + list[5] = new Option("nobody", "nobody"); + return (list); + + } // initPrimaryGroupList + + // Generate the list of secondary group names. + // Typically accessed from underlying OS. + private Option[] initSecondaryGroupList() { + + Option[] list = new Option[11]; + list[0] = new Option("east", "east"); + list[1] = new Option("bur_eng", "bur_eng"); + list[2] = new Option("bur_mktg", "bur_mktg"); + list[3] = new Option("central", "central"); + list[4] = new Option("brm_eng", "brm_eng"); + list[5] = new Option("brm_mktg", "brm_mktg"); + list[6] = new Option("west", "west"); + list[7] = new Option("mpk_eng", "mpk_eng"); + list[8] = new Option("mpk_mktg", "mpk_mktg"); + list[9] = new Option("sca_eng", "sca_eng"); + list[10] = new Option("sca_mktg", "sca_mktg"); + return (list); + + } // initSecondaryGroupList + + // Reset state. Called by wizard event handler when + // wizard is complete. Method is package protected. + void clearState() { + + userName = ""; + userDesc = ""; + userUid = ""; + uidAutoGenerate = false; + uidSet = true; + userPswd = ""; + userPswdConfirm = ""; + pswdNow = true; + pswdLocked = false; + pswdFirstLogin = false; + primaryGroupName = "other"; + secondaryGroupNames = new String[0]; + homeServer = ""; + homePath = ""; + resultMessage = "Invalid results!"; + + } // clearState + +} // SimpleWizardBackingBean + +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Event handling class +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +/** + * Handle wizard events based on wizard NavigationEvent state. + * We handle the FINISH event to indicate that we must perform + * the actual operation of adding the new user account and then + * set the results message based on the outcome of that operation. + * We handle the COMPLETE event to indicate we should reset all + * wizard properties so the next execution will start with + * initial values. All other events are ignored. + */ +class SimpleWizardEventListener implements WizardEventListener { + + // Reference to our backing bean instance. + private SimpleWizardBackingBean bean; + + /** Constructor accepts backing bean reference */ + public SimpleWizardEventListener(SimpleWizardBackingBean bean) { + + this.bean = bean; + + } // Constructor + + /** Wizard event handling method */ + public boolean handleEvent(WizardEvent event) { + + Wizard wiz = event.getWizard(); + // WizardStep step = event.getStep(); + // String stepTitle = step.getTitle(); + // System.out.println("Wizard event step: " + stepTitle); + switch (event.getNavigationEvent()) { + + // FINISH event indicates we can add our new user. + // In this example, we simply set the success message. + case WizardEvent.FINISH: + String messageString = + MessageUtil.getMessage("wiz_simple_result", + bean.getUserName()); + bean.setResultMessage(messageString); + break; + + // COMPLETE event indicates we are all done. + // Reset the wizard be removing all its children, + // which forces next execution to reinitialize them, + // and clearing the bean state. + case WizardEvent.COMPLETE: + wiz.getChildren().clear(); + bean.clearState(); + break; + + // All other events are ignored. + default: + + break; + } // End of switch + return (true); + + } // handleEvent + + // Methods for JSF state saving must be implemented. + // Since we are not participating in state saving, we + // return true for isTransient. + public void setTransient(boolean transientFlag) { } + public boolean isTransient() { return true; } + public Object saveState(FacesContext context) { return null; } + public void restoreState(FacesContext context, Object state) { } + +} // SimpleWizardEventListener