Moving to root below branch label

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2005-12-08 07:13:07 +00:00
commit d051d1153c
920 changed files with 98871 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.io.Serializable;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* @author Kevin Roast
*/
public interface IBreadcrumbHandler extends Serializable
{
/**
* Override Object.toString()
*
* @return the element display label for this handler instance.
*/
public String toString();
/**
* Perform appropriate processing logic and then return a JSF navigation outcome.
* This method will be called by the framework when the handler instance is selected by the user.
*
* @param breadcrumb The UIBreadcrumb component that caused the navigation
*
* @return JSF navigation outcome
*/
public String navigationOutcome(UIBreadcrumb breadcrumb);
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.io.IOException;
import javax.faces.component.UIComponentBase;
import javax.faces.context.ResponseWriter;
/**
* @author kevinr
*/
public abstract class SelfRenderingComponent extends UIComponentBase
{
/**
* Default Constructor
*/
public SelfRenderingComponent()
{
// specifically set the renderer type to null to indicate to the framework
// that this component renders itself - there is no abstract renderer class
setRendererType(null);
}
/**
* Helper to output an attribute to the output stream
*
* @param out ResponseWriter
* @param attr attribute value object (cannot be null)
* @param mapping mapping to output as e.g. style="..."
*
* @throws IOException
*/
protected static void outputAttribute(ResponseWriter out, Object attr, String mapping)
throws IOException
{
if (attr != null)
{
out.write(' ');
out.write(mapping);
out.write("=\"");
out.write(attr.toString());
out.write('"');
}
}
}

View File

@@ -0,0 +1,332 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.util.HashMap;
import java.util.Map;
import javax.faces.component.UICommand;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
/**
* @author kevinr
*/
public class UIActionLink extends UICommand
{
// ------------------------------------------------------------------------------
// Construction
/**
* Default Constructor
*/
public UIActionLink()
{
setRendererType("org.alfresco.faces.ActionLinkRenderer");
}
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Controls";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.padding = (Integer)values[1];
this.image = (String)values[2];
this.showLink = (Boolean)values[3];
this.params = (Map)values[4];
this.href = (String)values[5];
this.tooltip = (String)values[6];
this.target = (String)values[7];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[8];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.padding;
values[2] = this.image;
values[3] = this.showLink;
values[4] = this.params;
values[5] = this.href;
values[6] = this.tooltip;
values[7] = this.target;
return (values);
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* Return the current child parameter map for this action link instance.
* This map is filled with name/value pairs from any child UIParameter components.
*
* @return Map of name/value pairs
*/
public Map<String, String> getParameterMap()
{
if (this.params == null)
{
this.params = new HashMap<String, String>(3, 1.0f);
}
return this.params;
}
/**
* Get whether to show the link as well as the image if specified
*
* @return true to show the link as well as the image if specified
*/
public boolean getShowLink()
{
ValueBinding vb = getValueBinding("showLink");
if (vb != null)
{
this.showLink = (Boolean)vb.getValue(getFacesContext());
}
if (this.showLink != null)
{
return this.showLink.booleanValue();
}
else
{
// return default
return true;
}
}
/**
* Set whether to show the link as well as the image if specified
*
* @param showLink Whether to show the link as well as the image if specified
*/
public void setShowLink(boolean showLink)
{
this.showLink = Boolean.valueOf(showLink);
}
/**
* Get the padding value for rendering this component in a table.
*
* @return the padding in pixels, if set != 0 then a table will be rendering around the items
*/
public int getPadding()
{
ValueBinding vb = getValueBinding("padding");
if (vb != null)
{
this.padding = (Integer)vb.getValue(getFacesContext());
}
if (this.padding != null)
{
return this.padding.intValue();
}
else
{
// return default
return 0;
}
}
/**
* Set the padding value for rendering this component in a table.
*
* @param padding value in pixels, if set != 0 then a table will be rendering around the items
*/
public void setPadding(int padding)
{
this.padding = padding;
}
/**
* Return the Image path to use for this actionlink.
* If an image is specified, it is shown in additon to the value text unless
* the 'showLink' property is set to 'false'.
*
* @return the image path to display
*/
public String getImage()
{
ValueBinding vb = getValueBinding("image");
if (vb != null)
{
this.image = (String)vb.getValue(getFacesContext());
}
return this.image;
}
/**
* Set the Image path to use for this actionlink.
* If an image is specified, it is shown in additon to the value text unless
* the 'showLink' property is set to 'false'.
*
* @param image Image path to display
*/
public void setImage(String image)
{
this.image = image;
}
/**
* @return Returns the href.
*/
public String getHref()
{
ValueBinding vb = getValueBinding("href");
if (vb != null)
{
this.href = (String)vb.getValue(getFacesContext());
}
return this.href;
}
/**
* @param href The href to set.
*/
public void setHref(String href)
{
this.href = href;
}
/**
* Get the tooltip title text
*
* @return the tooltip
*/
public String getTooltip()
{
ValueBinding vb = getValueBinding("tooltip");
if (vb != null)
{
this.tooltip = (String)vb.getValue(getFacesContext());
}
return this.tooltip;
}
/**
* Set the tooltip title text
*
* @param tooltip the tooltip
*/
public void setTooltip(String tooltip)
{
this.tooltip = tooltip;
}
/**
* Get the target
*
* @return the target
*/
public String getTarget()
{
ValueBinding vb = getValueBinding("target");
if (vb != null)
{
this.target = (String)vb.getValue(getFacesContext());
}
return this.target;
}
/**
* Set the target
*
* @param target the target
*/
public void setTarget(String target)
{
this.target = target;
}
/**
* Returns the onclick handler
*
* @return The onclick handler
*/
public String getOnclick()
{
ValueBinding vb = getValueBinding("onclick");
if (vb != null)
{
this.onclick = (String)vb.getValue(getFacesContext());
}
return this.onclick;
}
/**
* Sets the onclick handler
*
* @param onclick The onclick handler
*/
public void setOnclick(String onclick)
{
this.onclick = onclick;
}
// ------------------------------------------------------------------------------
// Private data
/** the padding value in pixels, if set != 0 then a table will be rendered around the items */
private Integer padding = null;
/** True to show the link as well as the image if specified */
private Boolean showLink = null;
/** If an image is specified, it is shown in additon to the value text */
private String image = null;
/** static href to use instead of an action/actionlistener */
private String href = null;
/** tooltip title text to display on the action link */
private String tooltip = null;
/** the target reference */
private String target = null;
/** the onclick handler */
private String onclick = null;
/** Map of child param name/values pairs */
private Map<String, String> params = null;
}

View File

@@ -0,0 +1,311 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
/**
* @author kevinr
*/
public class UIBreadcrumb extends UICommand
{
// ------------------------------------------------------------------------------
// Construction
/**
* Default Constructor
*/
public UIBreadcrumb()
{
setRendererType("org.alfresco.faces.BreadcrumbRenderer");
}
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Controls";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.separator = (String)values[1];
this.showRoot = (Boolean)values[2];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[3];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.separator;
values[2] = this.showRoot;
return (values);
}
/**
* @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof BreadcrumbEvent)
{
setSelectedPathIndex( ((BreadcrumbEvent)event).SelectedIndex );
}
// default ActionEvent processing for a UICommand
super.broadcast(event);
}
/**
* Set the selected path index. This modifies the current path value.
*
* @return last selected path index
*/
public void setSelectedPathIndex(int index)
{
// getValue() will return a List of IBreadcrumbHandler (see impl below)
List<IBreadcrumbHandler> elements = (List)getValue();
if (elements.size() >= index)
{
// copy path elements up to the selected index to a new List
List<IBreadcrumbHandler> path = new ArrayList<IBreadcrumbHandler>(index + 1);
path.addAll(elements.subList(0, index + 1));
// set the new List as our new path value
setValue(path);
// call the app logic for the element handler and perform any required navigation
String outcome = path.get(index).navigationOutcome(this);
if (outcome != null)
{
String viewId = getFacesContext().getViewRoot().getViewId();
getFacesContext().getApplication().getNavigationHandler().handleNavigation(
getFacesContext(), viewId, outcome);
}
}
}
/**
* Override getValue() to deal with converting a String path into a valid List of IBreadcrumbHandler
*/
public Object getValue()
{
List<IBreadcrumbHandler> elements = null;
Object value = super.getValue();
if (value instanceof String)
{
elements = new ArrayList(8);
// found a String based path - convert to List of IBreadcrumbHandler instances
StringTokenizer t = new StringTokenizer((String)value, SEPARATOR);
while (t.hasMoreTokens() == true)
{
IBreadcrumbHandler handler = new DefaultPathHandler(t.nextToken());
elements.add(handler);
}
// save result so we don't need to repeat the conversion
setValue(elements);
}
else if (value instanceof List)
{
elements = (List)value;
}
else if (value != null)
{
throw new IllegalArgumentException("UIBreadcrumb value must be a String path or List of IBreadcrumbHandler!");
}
else
{
elements = new ArrayList(8);
}
return elements;
}
/**
* Append a handler object to the current breadcrumb structure
*
* @param handler The IBreadcrumbHandler to append
*/
public void appendHandler(IBreadcrumbHandler handler)
{
if (handler == null)
{
throw new NullPointerException("IBreadcrumbHandler instance cannot be null!");
}
List elements = (List)getValue();
elements.add(handler);
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* Get the separator string to output between each breadcrumb element
*
* @return separator string
*/
public String getSeparator()
{
ValueBinding vb = getValueBinding("separator");
if (vb != null)
{
this.separator = (String)vb.getValue(getFacesContext());
}
return this.separator;
}
/**
* Set separator
*
* @param separator the separator string to output between each breadcrumb element
*/
public void setSeparator(String separator)
{
this.separator = separator;
}
/**
* Get whether to show the root of the path
*
* @return true to show the root of the path, false to hide it
*/
public boolean getShowRoot()
{
ValueBinding vb = getValueBinding("showRoot");
if (vb != null)
{
this.showRoot = (Boolean)vb.getValue(getFacesContext());
}
if (this.showRoot != null)
{
return this.showRoot.booleanValue();
}
else
{
// return default
return true;
}
}
/**
* Set whether to show the root of the path
*
* @param showRoot Whether to show the root of the path
*/
public void setShowRoot(boolean showRoot)
{
this.showRoot = Boolean.valueOf(showRoot);
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the clicking of a breadcrumb element.
*/
public static class BreadcrumbEvent extends ActionEvent
{
public BreadcrumbEvent(UIComponent component, int selectedIndex)
{
super(component);
SelectedIndex = selectedIndex;
}
public int SelectedIndex = 0;
}
/**
* Class representing a handler for the default String path based breadcrumb
*/
private static class DefaultPathHandler implements IBreadcrumbHandler
{
/**
* Constructor
*
* @param label The element display label
*/
public DefaultPathHandler(String label)
{
this.label = label;
}
/**
* Return the element display label
*/
public String toString()
{
return this.label;
}
/**
* @see org.alfresco.web.ui.common.component.IBreadcrumbHandler#navigationOutcome(org.alfresco.web.ui.common.component.UIBreadcrumb)
*/
public String navigationOutcome(UIBreadcrumb breadcrumb)
{
// no outcome for the default handler - return to current page
return null;
}
private String label;
}
// ------------------------------------------------------------------------------
// Private data
/** visible separator value */
private String separator = null;
/** true to show the root of the breadcrumb path, false otherwise */
private Boolean showRoot = null;
/** the separator for a breadcrumb path value */
public final static String SEPARATOR = "/";
}

View File

@@ -0,0 +1,644 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import javax.faces.model.SelectItem;
import org.alfresco.web.app.Application;
import org.alfresco.web.ui.common.Utils;
/**
* @author Kevin Roast
*/
public class UIGenericPicker extends UICommand
{
/** action ids */
private final static int ACTION_NONE = -1;
private final static int ACTION_SEARCH = 0;
private final static int ACTION_CLEAR = 1;
private final static int ACTION_FILTER = 2;
private final static int ACTION_ADD = 3;
/** form field postfixes */
private final static String FIELD_FILTER = "_filter";
private final static String FIELD_CONTAINS = "_contains";
private final static String FIELD_RESULTS = "_results";
/** I18N message strings */
private final static String MSG_SEARCH = "search";
private final static String MSG_CLEAR = "clear";
private final static String MSG_ADD = "add";
private final static String MSG_RESULTS1 = "results_contains";
private final static String MSG_RESULTS2 = "results_contains_filter";
private final static int DEFAULT_HEIGHT = 100;
private final static int DEFAULT_WIDTH = 250;
private MethodBinding queryCallback = null;
private Boolean showFilter = null;
private Boolean showContains = null;
private Boolean showAddButton = null;
private Boolean filterRefresh = null;
private String addButtonLabel;
private Integer width = null;
private Integer height = null;
private SelectItem[] filters = null;
private int filterIndex = 0;
private String contains = "";
private String[] selectedResults = null;
private SelectItem[] currentResults = null;
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.GenericPicker";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
showFilter = (Boolean)values[1];
showContains = (Boolean)values[2];
showAddButton = (Boolean)values[3];
addButtonLabel = (String)values[4];
width = (Integer)values[5];
height = (Integer)values[6];
filterIndex = (Integer)values[7];
contains = (String)values[8];
queryCallback = (MethodBinding)values[9];
selectedResults = (String[])values[10];
currentResults = (SelectItem[])values[11];
filters = (SelectItem[])values[12];
filterRefresh = (Boolean)values[13];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[14];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = showFilter;
values[2] = showContains;
values[3] = showAddButton;
values[4] = addButtonLabel;
values[5] = width;
values[6] = height;
values[7] = filterIndex;
values[8] = contains;
values[9] = queryCallback;
values[10] = selectedResults;
values[11] = currentResults;
values[12] = filters;
values[13] = filterRefresh;
return (values);
}
/**
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
Map valuesMap = context.getExternalContext().getRequestParameterValuesMap();
String fieldId = getHiddenFieldName();
String value = (String)requestMap.get(fieldId);
int action = ACTION_NONE;
if (value != null && value.length() != 0)
{
// decode the values - we are expecting an action identifier
action = Integer.parseInt(value);
}
// we always process these values to keep the component up-to-date
// now find the Filter drop-down value
int filterIndex = 0;
String strFilterIndex = (String)requestMap.get(fieldId + FIELD_FILTER);
if (strFilterIndex != null && strFilterIndex.length() != 0)
{
filterIndex = Integer.parseInt(strFilterIndex);
}
// and the Contains text box value
String contains = (String)requestMap.get(fieldId + FIELD_CONTAINS);
// and the Results selections
String[] results = (String[])valuesMap.get(fieldId + FIELD_RESULTS);
// queue an event
PickerEvent event = new PickerEvent(this, action, filterIndex, contains, results);
queueEvent(event);
}
/**
* @see javax.faces.component.UIComponentBase#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof PickerEvent)
{
PickerEvent pickerEvent = (PickerEvent)event;
// set component state from event properties
this.filterIndex = pickerEvent.FilterIndex;
this.contains = pickerEvent.Contains;
this.selectedResults = pickerEvent.Results;
// delegate to appropriate action logic
switch (pickerEvent.Action)
{
case ACTION_ADD:
// call super for actionlistener execution
// it's up to the handler to get the results from the getSelectedResults() method
super.broadcast(event);
break;
case ACTION_CLEAR:
this.contains = "";
this.filterIndex = 0;
this.selectedResults = null;
this.currentResults = null;
break;
case ACTION_FILTER:
// filter changed then query with new settings
case ACTION_SEARCH:
// query with current settings
MethodBinding callback = getQueryCallback();
if (callback != null)
{
// use reflection to execute the query callback method and retrieve results
Object result = callback.invoke(getFacesContext(), new Object[] {
this.filterIndex, this.contains});
if (result instanceof SelectItem[])
{
this.currentResults = (SelectItem[])result;
}
else
{
this.currentResults = null;
}
}
break;
}
}
else
{
super.broadcast(event);
}
}
/**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
ResourceBundle bundle = Application.getBundle(context);
String clientId = getClientId(context);
// start outer table
out.write("<table border=0 cellspacing=4 cellpadding=0>");
// top row
out.write("<tr valign=top><td>");
// filter drop-down
if (getShowFilter() == true)
{
out.write("<select name='");
out.write(clientId + FIELD_FILTER);
out.write("' size='1'");
// apply onchange Form submit here if component attributes require it
if (getFilterRefresh() == true)
{
out.write(" onchange=\"");
out.write(generateFormSubmit(context, ACTION_FILTER));
out.write("\"");
}
out.write(">");
// output filter options
SelectItem[] items = getFilterOptions();
if (items != null)
{
for (int i=0; i<items.length; i++)
{
out.write("<option value=\"");
out.write(items[i].getValue().toString());
if (this.filterIndex != i)
{
out.write("\">");
}
else
{
out.write("\" selected=\"true\">");
}
out.write(items[i].getLabel());
out.write("</option>");
}
}
out.write("</select>");
}
out.write("</td><td align=right>");
// Contains textbox
if (getShowContains() == true)
{
out.write("<input name='");
out.write(clientId + FIELD_CONTAINS);
out.write("' type='text' maxlength='256' style='width:120px' value=\"");
out.write(Utils.replace(this.contains, "\"", "&quot;"));
out.write("\">&nbsp;");
}
// Search button
out.write("<input type='submit' value='");
out.write(Utils.encode(bundle.getString(MSG_SEARCH)));
out.write("' onclick=\"");
out.write(generateFormSubmit(context, ACTION_SEARCH));
out.write("\">");
out.write("</td></tr>");
// information row
if (this.currentResults != null && getShowContains() == true)
{
out.write("<tr><td colspan=3>");
String resultsMsg;
if (getShowFilter() == false)
{
resultsMsg = MessageFormat.format(bundle.getString(MSG_RESULTS1), new Object[] {this.contains});
}
else
{
String filterMsg = this.filters[this.filterIndex].getLabel();
resultsMsg = MessageFormat.format(bundle.getString(MSG_RESULTS2), new Object[] {this.contains, filterMsg});
}
out.write(resultsMsg);
out.write("&nbsp;");
out.write("<a href='#' onclick=\"");
out.write(generateFormSubmit(context, ACTION_CLEAR));
out.write("\">");
out.write(Utils.encode(bundle.getString(MSG_CLEAR)));
out.write("</a></td></tr>");
}
// results list row
out.write("<tr><td colspan=2>");
out.write("<select size='8' style='width:");
out.write(Integer.toString(getWidth()));
out.write("px;height:");
out.write(Integer.toString(getHeight()));
out.write("px' name='");
out.write(clientId + FIELD_RESULTS);
out.write("' multiple>");
// results
if (currentResults != null)
{
// show each of the items in the results listbox
for (int i=0; i<currentResults.length; i++)
{
out.write("<option value=\"");
out.write(currentResults[i].getValue().toString());
out.write("\">");
out.write(currentResults[i].getLabel());
out.write("</option>");
}
}
// end results list
out.write("</select>");
out.write("</td></tr>");
// bottom row - add button
if (getShowAddButton() == true)
{
out.write("<tr><td colspan=2>");
out.write("<input type='submit' value='");
String msg = getAddButtonLabel();
if (msg == null || msg.length() == 0)
{
msg = bundle.getString(MSG_ADD);
}
out.write(Utils.encode(msg));
out.write("' onclick=\"");
out.write(generateFormSubmit(context, ACTION_ADD));
out.write("\">");
out.write("</td></tr>");
}
// end outer table
out.write("</table>");
}
/**
* @return the filter options
*/
public SelectItem[] getFilterOptions()
{
if (this.filters == null)
{
ValueBinding vb = (ValueBinding)getValueBinding("filters");
if (vb != null)
{
this.filters = (SelectItem[])vb.getValue(getFacesContext());
}
}
return this.filters;
}
/**
* @return current filter drop-down selected index value
*/
public int getFilterIndex()
{
return this.filterIndex;
}
/**
* @return Returns the addButtonLabel.
*/
public String getAddButtonLabel()
{
ValueBinding vb = getValueBinding("addButtonLabel");
if (vb != null)
{
this.addButtonLabel = (String)vb.getValue(getFacesContext());
}
return this.addButtonLabel;
}
/**
* @param addButtonLabel The addButtonLabel to set.
*/
public void setAddButtonLabel(String addButtonLabel)
{
this.addButtonLabel = addButtonLabel;
}
/**
* @return Returns the showAddButton.
*/
public boolean getShowAddButton()
{
ValueBinding vb = getValueBinding("showAddButton");
if (vb != null)
{
this.showAddButton = (Boolean)vb.getValue(getFacesContext());
}
return showAddButton != null ? showAddButton.booleanValue() : true;
}
/**
* @param showAddButton The showAddButton to set.
*/
public void setShowAddButton(boolean showAddButton)
{
this.showAddButton = Boolean.valueOf(showAddButton);
}
/**
* @return Returns the showContains.
*/
public boolean getShowContains()
{
ValueBinding vb = getValueBinding("showContains");
if (vb != null)
{
this.showContains = (Boolean)vb.getValue(getFacesContext());
}
return showContains != null ? showContains.booleanValue() : true;
}
/**
* @param showContains The showContains to set.
*/
public void setShowContains(boolean showContains)
{
this.showContains = Boolean.valueOf(showContains);
}
/**
* @return Returns the showFilter.
*/
public boolean getShowFilter()
{
ValueBinding vb = getValueBinding("showFilter");
if (vb != null)
{
this.showFilter = (Boolean)vb.getValue(getFacesContext());
}
return showFilter != null ? showFilter.booleanValue() : true;
}
/**
* @param showFilter The showFilter to set.
*/
public void setShowFilter(boolean showFilter)
{
this.showFilter = Boolean.valueOf(showFilter);
}
/**
* @return Returns the filterRefresh.
*/
public boolean getFilterRefresh()
{
ValueBinding vb = getValueBinding("filterRefresh");
if (vb != null)
{
this.filterRefresh = (Boolean)vb.getValue(getFacesContext());
}
return filterRefresh != null ? filterRefresh.booleanValue() : false;
}
/**
* @param filterRefresh The filterRefresh to set.
*/
public void setFilterRefresh(boolean filterRefresh)
{
this.filterRefresh = Boolean.valueOf(filterRefresh);
}
/**
* @return Returns the width.
*/
public int getWidth()
{
ValueBinding vb = getValueBinding("width");
if (vb != null)
{
this.width = (Integer)vb.getValue(getFacesContext());
}
return width != null ? width.intValue() : DEFAULT_WIDTH;
}
/**
* @param width The width to set.
*/
public void setWidth(int width)
{
this.width = Integer.valueOf(width);
}
/**
* @return Returns the height.
*/
public int getHeight()
{
ValueBinding vb = getValueBinding("height");
if (vb != null)
{
this.height = (Integer)vb.getValue(getFacesContext());
}
return height != null ? height.intValue() : DEFAULT_HEIGHT;
}
/**
* @param height The height to set.
*/
public void setHeight(int height)
{
this.height = Integer.valueOf(height);
}
/**
* @return Returns the queryCallback.
*/
public MethodBinding getQueryCallback()
{
return this.queryCallback;
}
/**
* @param binding The queryCallback MethodBinding to set.
*/
public void setQueryCallback(MethodBinding binding)
{
this.queryCallback = binding;
}
/**
* @return The selected results. An array of whatever string objects were attached to the
* SelectItem[] objects supplied as the result of the picker query.
*/
public String[] getSelectedResults()
{
return this.selectedResults;
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* We use a hidden field per picker instance on the page.
*
* @return hidden field name
*/
private String getHiddenFieldName()
{
return getClientId(getFacesContext());
}
/**
* Generate FORM submit JavaScript for the specified action
*
* @param context FacesContext
* @param action Action index
*
* @return FORM submit JavaScript
*/
private String generateFormSubmit(FacesContext context, int action)
{
return Utils.generateFormSubmit(context, this, getHiddenFieldName(), Integer.toString(action));
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the an action relevant to the Generic Selector component.
*/
public static class PickerEvent extends ActionEvent
{
public PickerEvent(UIComponent component, int action, int filterIndex, String contains, String[] results)
{
super(component);
Action = action;
FilterIndex = filterIndex;
Contains = contains;
Results = results;
}
public int Action;
public int FilterIndex;
public String Contains;
public String[] Results;
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Component to represent a selectable list of images
*
* @author gavinc
*/
public class UIImagePicker extends UIInput
{
private static Log logger = LogFactory.getLog(UIImagePicker.class);
/**
* Default constructor
*/
public UIImagePicker()
{
// set the default renderer for an image picker component
setRendererType("org.alfresco.faces.Radio");
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.ImagePicker";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[1];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
return (values);
}
}

View File

@@ -0,0 +1,190 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
/**
* @author kevinr
*/
public class UIListItem extends SelfRenderingComponent
{
// ------------------------------------------------------------------------------
// Component Impl
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Controls";
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[5];
values[0] = super.saveState(context);
values[1] = this.value;
values[2] = this.disabled;
values[3] = this.label;
values[4] = this.tooltip;
return ((Object) (values));
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
super.restoreState(context, values[0]);
this.value = values[1];
this.disabled = (Boolean)values[2];
this.label = (String)values[3];
this.tooltip = (String)values[4];
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* Get the value - the value is used in a equals() match against the current value in the
* parent ModeList component to set the selected item.
*
* @return the value
*/
public Object getValue()
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.value = vb.getValue(getFacesContext());
}
return this.value;
}
/**
* Set the value - the value is used in a equals() match against the current value in the
* parent ModeList component to set the selected item.
*
* @param value the value
*/
public void setValue(Object value)
{
this.value = value;
}
/**
* Returns the disabled flag
*
* @return true if the mode list is disabled
*/
public boolean isDisabled()
{
ValueBinding vb = getValueBinding("disabled");
if (vb != null)
{
this.disabled = (Boolean)vb.getValue(getFacesContext());
}
if (this.disabled != null)
{
return this.disabled.booleanValue();
}
else
{
// return the default
return false;
}
}
/**
* Sets whether the mode list is disabled
*
* @param disabled the disabled flag
*/
public void setDisabled(boolean disabled)
{
this.disabled = disabled;
}
/**
* @return Returns the label.
*/
public String getLabel()
{
ValueBinding vb = getValueBinding("label");
if (vb != null)
{
this.label = (String)vb.getValue(getFacesContext());
}
return this.label;
}
/**
* @param label The label to set.
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* @return Returns the tooltip.
*/
public String getTooltip()
{
ValueBinding vb = getValueBinding("tooltip");
if (vb != null)
{
this.tooltip = (String)vb.getValue(getFacesContext());
}
return this.tooltip;
}
/**
* @param tooltip The tooltip to set.
*/
public void setTooltip(String tooltip)
{
this.tooltip = tooltip;
}
// ------------------------------------------------------------------------------
// Private data
/** the component value */
private Object value = null;
/** disabled flag */
private Boolean disabled = null;
/** the tooltip */
private String tooltip;
/** the label */
private String label;
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the GNU Lesser General Public License as
* published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
/**
* Allows a group of UIListItem objects to be represented.
*
* @author gavinc
*/
public class UIListItems extends SelfRenderingComponent
{
private Object value;
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.ListItems";
}
/**
* @return Returns the object holding the decriptions
*/
public Object getValue()
{
if (this.value == null)
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.value = vb.getValue(getFacesContext());
}
}
return this.value;
}
/**
* @param value Sets the object holding the description
*/
public void setValue(Object value)
{
this.value = value;
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.value = values[1];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[2];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.value;
return (values);
}
}

View File

@@ -0,0 +1,219 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.io.IOException;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.web.ui.common.Utils;
/**
* @author Kevin Roast
*/
public class UIMenu extends SelfRenderingComponent
{
// ------------------------------------------------------------------------------
// Component Impl
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Controls";
}
/**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
// output a textual label with an optional icon to show the menu
String menuId = getNextMenuId(context);
out.write("<a href='#' onclick=\"javascript:_toggleMenu(event, '");
out.write(menuId);
out.write("');return false;\"");
outputAttribute(out, getAttributes().get("style"), "style");
outputAttribute(out, getAttributes().get("styleClass"), "class");
outputAttribute(out, getTooltip(), "title");
out.write('>');
// output label text
String label = getLabel();
if (label != null)
{
out.write("<span>");
out.write(Utils.encode(label));
out.write("</span>");
}
// output image
if (getAttributes().get("image") != null)
{
out.write(Utils.buildImageTag(context, (String)getAttributes().get("image"), null, "absmiddle"));
}
out.write("</a>");
// output the hidden DIV section to contain the menu item table
// also output the javascript handlers used to hide the menu after a delay of non-use
out.write("<br><div id='");
out.write(menuId);
out.write("' style=\"position:absolute;display:none;padding-left:2px;\">");
out.write("<table border=0 cellpadding=0");
outputAttribute(out, getAttributes().get("itemSpacing"), "cellspacing");
outputAttribute(out, getAttributes().get("menuStyle"), "style");
outputAttribute(out, getAttributes().get("menuStyleClass"), "class");
out.write(">");
}
/**
* @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
*/
public void encodeEnd(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
// end the menu table and the hidden DIV section
out.write("</table></div>");
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.label = (String)values[1];
this.tooltip = (String)values[2];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[3];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.label;
values[2] = this.tooltip;
return values;
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* @return Returns the label.
*/
public String getLabel()
{
ValueBinding vb = getValueBinding("label");
if (vb != null)
{
this.label = (String)vb.getValue(getFacesContext());
}
return this.label;
}
/**
* @param label The label to set.
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* @return Returns the tooltip.
*/
public String getTooltip()
{
ValueBinding vb = getValueBinding("tooltip");
if (vb != null)
{
this.tooltip = (String)vb.getValue(getFacesContext());
}
return this.tooltip;
}
/**
* @param tooltip The tooltip to set.
*/
public void setTooltip(String tooltip)
{
this.tooltip = tooltip;
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* Return the next usable menu DIV id in a sequence
*
* @param context FacesContext
*
* @return next menu ID
*/
private String getNextMenuId(FacesContext context)
{
Integer val = (Integer)context.getExternalContext().getRequestMap().get(MENU_ID_KEY);
if (val == null)
{
val = Integer.valueOf(0);
}
// build next id in sequence
String id = getClientId(context) + '_' + val.toString();
// save incremented value in the request ready for next menu component instance
val = Integer.valueOf( val.intValue() + 1 );
context.getExternalContext().getRequestMap().put(MENU_ID_KEY, val);
return id;
}
// ------------------------------------------------------------------------------
// Private members
private final static String MENU_ID_KEY = "__awc_menu_id";
private String label;
private String tooltip;
}

View File

@@ -0,0 +1,262 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
/**
* @author Kevin Roast
*/
public class UIModeList extends UICommand
{
// ------------------------------------------------------------------------------
// Construction
/**
* Default constructor
*/
public UIModeList()
{
setRendererType("org.alfresco.faces.ModeListRenderer");
}
// ------------------------------------------------------------------------------
// Component Impl
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Controls";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.iconColumnWidth = (Integer)values[1];
this.horizontal = (Boolean)values[2];
this.disabled = (Boolean)values[3];
this.label = (String)values[4];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[5];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.iconColumnWidth;
values[2] = this.horizontal;
values[3] = this.disabled;
values[4] = this.label;
return (values);
}
/**
* @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof ModeListItemSelectedEvent)
{
// found an event for us, update the value for this component
setValue( ((ModeListItemSelectedEvent)event).SelectedValue );
}
// default ActionEvent processing for a UICommand
super.broadcast(event);
}
// ------------------------------------------------------------------------------
// Strongly typed property accessors
/**
* Get the horizontal rendering flag
*
* @return true for horizontal rendering, false otherwise
*/
public boolean isHorizontal()
{
ValueBinding vb = getValueBinding("horizontal");
if (vb != null)
{
this.horizontal = (Boolean)vb.getValue(getFacesContext());
}
if (this.horizontal != null)
{
return this.horizontal.booleanValue();
}
else
{
// return the default
return false;
}
}
/**
* Set true for horizontal rendering, false otherwise
*
* @param horizontal the horizontal
*/
public void setHorizontal(boolean horizontal)
{
this.horizontal = horizontal;
}
/**
* Get the icon column width
*
* @return the icon column width
*/
public int getIconColumnWidth()
{
ValueBinding vb = getValueBinding("iconColumnWidth");
if (vb != null)
{
this.iconColumnWidth = (Integer)vb.getValue(getFacesContext());
}
if (this.iconColumnWidth != null)
{
return this.iconColumnWidth.intValue();
}
else
{
// return the default
return 20;
}
}
/**
* Set the icon column width
*
* @param iconColumnWidth the icon column width
*/
public void setIconColumnWidth(int iconColumnWidth)
{
this.iconColumnWidth = Integer.valueOf(iconColumnWidth);
}
/**
* Returns the disabled flag
*
* @return true if the mode list is disabled
*/
public boolean isDisabled()
{
ValueBinding vb = getValueBinding("disabled");
if (vb != null)
{
this.disabled = (Boolean)vb.getValue(getFacesContext());
}
if (this.disabled != null)
{
return this.disabled.booleanValue();
}
else
{
// return the default
return false;
}
}
/**
* Sets whether the mode list is disabled
*
* @param disabled the disabled flag
*/
public void setDisabled(boolean disabled)
{
this.disabled = disabled;
}
/**
* @return Returns the label.
*/
public String getLabel()
{
ValueBinding vb = getValueBinding("label");
if (vb != null)
{
this.label = (String)vb.getValue(getFacesContext());
}
return this.label;
}
/**
* @param label The label to set.
*/
public void setLabel(String label)
{
this.label = label;
}
// ------------------------------------------------------------------------------
// Private data
/** the icon column width */
private Integer iconColumnWidth;
/** true for horizontal rendering, false otherwise */
private Boolean horizontal = null;
/** disabled flag */
private Boolean disabled = null;
/** the label */
private String label;
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing a change in selection for a ModeList component.
*/
public static class ModeListItemSelectedEvent extends ActionEvent
{
private static final long serialVersionUID = 3618135654274774322L;
public ModeListItemSelectedEvent(UIComponent component, Object selectedValue)
{
super(component);
SelectedValue = selectedValue;
}
public Object SelectedValue = null;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the GNU Lesser General Public License as
* published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.io.IOException;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
/**
* Component that simply renders text
*
* @author gavinc
*/
public class UIOutputText extends UIOutput
{
/**
* Default constructor
*/
public UIOutputText()
{
setRendererType(null);
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.OutputText";
}
/**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
out.write((String)getValue());
}
}

View File

@@ -0,0 +1,606 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.NamingContainer;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import org.alfresco.web.ui.common.PanelGenerator;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.WebResources;
/**
* @author kevinr
*/
public class UIPanel extends UICommand
{
// ------------------------------------------------------------------------------
// Component Impl
/**
* Default constructor
*/
public UIPanel()
{
setRendererType(null);
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Controls";
}
/**
* Return the UI Component to be displayed on the right of the panel title area
*
* @return UIComponent
*/
public UIComponent getTitleComponent()
{
UIComponent titleComponent = null;
// attempt to find a component with the specified ID
String facetsId = getFacetsId();
if (facetsId != null)
{
UIForm parent = Utils.getParentForm(FacesContext.getCurrentInstance(), this);
UIComponent facetsComponent = parent.findComponent(facetsId);
if (facetsComponent != null)
{
// get the 'title' facet from the component
titleComponent = facetsComponent.getFacet("title");
}
}
return titleComponent;
}
/**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
// determine if we have a component on the header
UIComponent titleComponent = getTitleComponent();
// determine whether we have any adornments
String label = getLabel();
if (label != null || isProgressive() == true || titleComponent != null)
{
this.hasAdornments = true;
}
// make sure we have a default background color for the content area
String bgcolor = getBgcolor();
if (bgcolor == null)
{
bgcolor = PanelGenerator.BGCOLOR_WHITE;
}
// determine if we have a bordered title area, note, we also need to have
// the content area border defined as well
if ((getTitleBgcolor() != null) && (getTitleBorder() != null) &&
(getBorder() != null) && this.hasAdornments)
{
this.hasBorderedTitleArea = true;
}
// output first part of border table
if (this.hasBorderedTitleArea)
{
PanelGenerator.generatePanelStart(
out,
context.getExternalContext().getRequestContextPath(),
getTitleBorder(),
getTitleBgcolor());
}
else if (getBorder() != null)
{
PanelGenerator.generatePanelStart(
out,
context.getExternalContext().getRequestContextPath(),
getBorder(),
bgcolor);
}
if (this.hasAdornments)
{
// start the containing table if we have any adornments
out.write("<table border='0' cellspacing='0' cellpadding='0' width='100%'><tr><td>");
}
// output progressive disclosure icon in appropriate state
// TODO: manage state of this icon via component Id!
if (isProgressive() == true)
{
out.write("<a href='#' onclick=\"");
String value = getClientId(context) + NamingContainer.SEPARATOR_CHAR + Boolean.toString(!isExpanded());
out.write(Utils.generateFormSubmit(context, this, getHiddenFieldName(), value));
out.write("\">");
if (isExpanded() == true)
{
out.write(Utils.buildImageTag(context, WebResources.IMAGE_EXPANDED, 11, 11, ""));
}
else
{
out.write(Utils.buildImageTag(context, WebResources.IMAGE_COLLAPSED, 11, 11, ""));
}
out.write("</a>&nbsp;&nbsp;");
}
// output textual label
if (label != null)
{
out.write("<span");
Utils.outputAttribute(out, getAttributes().get("style"), "style");
Utils.outputAttribute(out, getAttributes().get("styleClass"), "class");
out.write('>');
out.write(Utils.encode(label));
out.write("</span>");
}
if (this.hasAdornments)
{
out.write("</td>");
}
// render the title component if supplied
if (titleComponent != null)
{
out.write("<td align='right'>");
Utils.encodeRecursive(context, titleComponent);
out.write("</td>");
}
if (this.hasAdornments)
{
out.write("</tr></table>");
}
// if we have the titled border area, output the middle section
if (this.hasBorderedTitleArea && isExpanded())
{
PanelGenerator.generateTitledPanelMiddle(
out,
context.getExternalContext().getRequestContextPath(),
getTitleBorder(),
getBorder(),
getBgcolor());
}
}
/**
* @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
*/
public void encodeEnd(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
// output final part of border table
if (this.hasBorderedTitleArea && isExpanded() == false)
{
PanelGenerator.generatePanelEnd(
out,
context.getExternalContext().getRequestContextPath(),
getTitleBorder());
}
else if (getBorder() != null)
{
PanelGenerator.generatePanelEnd(
out,
context.getExternalContext().getRequestContextPath(),
getBorder());
}
}
/**
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = getHiddenFieldName();
String value = (String)requestMap.get(fieldId);
// we encoded the value to start with our Id
if (value != null && value.startsWith(getClientId(context)))
{
// we were clicked, strip out the value
value = value.substring(getClientId(context).length() + 1);
// the expand/collapse icon was clicked, so toggle the state
ExpandedEvent event = new ExpandedEvent(this, Boolean.parseBoolean(value));
queueEvent(event);
//
// TODO: See http://forums.java.sun.com/thread.jspa?threadID=524925&start=15&tstart=0
// Bug/known issue in JSF 1.1 RI
// This causes a problem where the View attempts to assign duplicate Ids
// to components when createUniqueId() on UIViewRoot is called before the
// render phase. This occurs in the Panel tag as it must call getComponent()
// early to decide whether to allow the tag to render contents or not.
//
// context.getViewRoot().setTransient(true);
//
// The other solution is to explicity give ALL child components of the
// panel a unique Id rather than a generated one!
}
}
/**
* @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof ExpandedEvent)
{
// expanded event - we handle this
setExpanded( ((ExpandedEvent)event).State );
if (getExpandedActionListener() != null)
{
Utils.processActionMethod(getFacesContext(), getExpandedActionListener(), (ExpandedEvent)event);
}
}
else
{
super.broadcast(event);
}
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
setExpanded( ((Boolean)values[1]).booleanValue() );
this.progressive = (Boolean)values[2];
this.border = (String)values[3];
this.bgcolor = (String)values[4];
this.label = (String)values[5];
this.titleBgcolor = (String)values[6];
this.titleBorder = (String)values[7];
this.expandedActionListener = (MethodBinding)values[8];
this.facetsId = (String)values[9];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[10];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = (isExpanded() ? Boolean.TRUE : Boolean.FALSE);
values[2] = this.progressive;
values[3] = this.border;
values[4] = this.bgcolor;
values[5] = this.label;
values[6] = this.titleBgcolor;
values[7] = this.titleBorder;
values[8] = this.expandedActionListener;
values[9] = this.facetsId;
return values;
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* @param binding The MethodBinding to call when expand/collapse is performed by the user.
*/
public void setExpandedActionListener(MethodBinding binding)
{
this.expandedActionListener = binding;
}
/**
* @return The MethodBinding to call when expand/collapse is performed by the user.
*/
public MethodBinding getExpandedActionListener()
{
return this.expandedActionListener;
}
/**
* @return Returns the bgcolor.
*/
public String getBgcolor()
{
ValueBinding vb = getValueBinding("bgcolor");
if (vb != null)
{
this.bgcolor = (String)vb.getValue(getFacesContext());
}
return this.bgcolor;
}
/**
* @param bgcolor The bgcolor to set.
*/
public void setBgcolor(String bgcolor)
{
this.bgcolor = bgcolor;
}
/**
* @return Returns the border name.
*/
public String getBorder()
{
ValueBinding vb = getValueBinding("border");
if (vb != null)
{
this.border = (String)vb.getValue(getFacesContext());
}
return this.border;
}
/**
* @param border The border name to user.
*/
public void setBorder(String border)
{
this.border = border;
}
/**
* @return Returns the bgcolor of the title area
*/
public String getTitleBgcolor()
{
ValueBinding vb = getValueBinding("titleBgcolor");
if (vb != null)
{
this.titleBgcolor = (String)vb.getValue(getFacesContext());
}
return this.titleBgcolor;
}
/**
* @param titleBgcolor Sets the bgcolor of the title area
*/
public void setTitleBgcolor(String titleBgcolor)
{
this.titleBgcolor = titleBgcolor;
}
/**
* @return Returns the border style of the title area
*/
public String getTitleBorder()
{
ValueBinding vb = getValueBinding("titleBorder");
if (vb != null)
{
this.titleBorder = (String)vb.getValue(getFacesContext());
}
return this.titleBorder;
}
/**
* @param titleBorder Sets the border style of the title area
*/
public void setTitleBorder(String titleBorder)
{
this.titleBorder = titleBorder;
}
/**
* @return Returns the label.
*/
public String getLabel()
{
ValueBinding vb = getValueBinding("label");
if (vb != null)
{
this.label = (String)vb.getValue(getFacesContext());
}
return this.label;
}
/**
* @param label The label to set.
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* @return Returns the progressive display setting.
*/
public boolean isProgressive()
{
ValueBinding vb = getValueBinding("progressive");
if (vb != null)
{
this.progressive = (Boolean)vb.getValue(getFacesContext());
}
if (this.progressive != null)
{
return this.progressive.booleanValue();
}
else
{
// return default
return false;
}
}
/**
* @param progressive The progressive display boolean to set.
*/
public void setProgressive(boolean progressive)
{
this.progressive = Boolean.valueOf(progressive);
}
/**
* Returns whether the component show allow rendering of its child components.
*/
public boolean isExpanded()
{
ValueBinding vb = getValueBinding("expanded");
if (vb != null)
{
this.expanded = (Boolean)vb.getValue(getFacesContext());
}
if (this.expanded != null)
{
return this.expanded.booleanValue();
}
else
{
// return default
return true;
}
}
/**
* Sets whether the component show allow rendering of its child components.
* For this component we change this value if the user indicates to change the
* hidden/visible state of the progressive panel.
*/
public void setExpanded(boolean expanded)
{
this.expanded = Boolean.valueOf(expanded);
}
/**
* Get the facets component Id to use
*
* @return the facets component Id
*/
public String getFacetsId()
{
ValueBinding vb = getValueBinding("facets");
if (vb != null)
{
this.facetsId = (String)vb.getValue(getFacesContext());
}
return this.facetsId;
}
/**
* Set the facets component Id to use
*
* @param facets the facets component Id
*/
public void setFacetsId(String facets)
{
this.facetsId = facets;
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* We use a hidden field name based on the parent form component Id and
* the string "panel" to give a hidden field name that can be shared by all panels
* within a single UIForm component.
*
* @return hidden field name
*/
private String getHiddenFieldName()
{
UIForm form = Utils.getParentForm(getFacesContext(), this);
return form.getClientId(getFacesContext()) + NamingContainer.SEPARATOR_CHAR + "panel";
}
// ------------------------------------------------------------------------------
// Private members
// component settings
private String border = null;
private String bgcolor = null;
private String titleBorder = null;
private String titleBgcolor = null;
private Boolean progressive = null;
private String label = null;
private String facetsId = null;
private MethodBinding expandedActionListener = null;
// component state
private boolean hasAdornments = false;
private boolean hasBorderedTitleArea = false;
private Boolean expanded = Boolean.TRUE;
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the an action relevant when the panel is expanded or collapsed.
*/
public static class ExpandedEvent extends ActionEvent
{
public ExpandedEvent(UIComponent component, boolean state)
{
super(component);
State = state;
}
public boolean State;
}
}

View File

@@ -0,0 +1,340 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import org.alfresco.web.app.Application;
import org.alfresco.web.ui.common.PanelGenerator;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.WebResources;
/**
* @author Kevin Roast
*/
public class UIStatusMessage extends SelfRenderingComponent
{
/**
* Default Constructor
*/
public UIStatusMessage()
{
setRendererType(null);
// add default message to display
FacesContext fc = FacesContext.getCurrentInstance();
String msg = Application.getMessage(fc, MSG_DEFAULT_STATUS);
String time = Utils.getTimeFormat(fc).format(new Date(System.currentTimeMillis()));
this.messages.add(new FacesMessage(FacesMessage.SEVERITY_INFO, time, msg));
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.StatusMessage";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.border = (String)values[1];
this.bgcolor = (String)values[2];
this.messages = (List)values[3];
this.currentMessage = ((Integer)values[4]).intValue();
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[5];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.border;
values[2] = this.bgcolor;
values[3] = this.messages;
values[4] = Integer.valueOf(this.currentMessage);
return values;
}
/**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
String bgColor = getBgcolor();
if (bgColor == null)
{
bgColor = PanelGenerator.BGCOLOR_WHITE;
}
String panel = getBorder();
if (panel != null)
{
PanelGenerator.generatePanelStart(out,
context.getExternalContext().getRequestContextPath(),
panel,
bgColor);
}
// Previous Message icon image - clicking shows previous message
out.write("<table width=100% cellspacing=0 cellpadding=0><tr><td>");
String field = getHiddenFieldName();
String leftValue = getClientId(context) + NamingContainer.SEPARATOR_CHAR + Integer.toString(ACTION_PREVIOUS);
String leftOnclick = Utils.generateFormSubmit(context, this, field, leftValue);
out.write(Utils.buildImageTag(context, WebResources.IMAGE_MOVELEFT, 12, 12, null, leftOnclick, "absmiddle"));
out.write("</td><td width=100% align=center>");
// get messages for the component and crop the stack to the maximum history size
Iterator<FacesMessage> msgIterator = context.getMessages(STATUS_MESSAGE);
while (msgIterator.hasNext())
{
if (messages.size() >= HISTORY_SIZE)
{
messages.remove(HISTORY_SIZE);
}
// add new messages to the stack in turn
messages.add(0, msgIterator.next());
// reset current message to top if new one added
currentMessage = 0;
}
// TODO: show different icon depending on SEVERITY of the message?
// Message text
String style = CSS_ERROR;
String icon = WebResources.IMAGE_INFO;
FacesMessage msg = messages.get(currentMessage);
if (msg.getSeverity() == FacesMessage.SEVERITY_INFO)
{
style = CSS_INFO;
}
else if (msg.getSeverity() == FacesMessage.SEVERITY_WARN)
{
style = CSS_WARNING;
}
out.write(Utils.buildImageTag(context, icon, null, "absmiddle"));
out.write("&nbsp;<span class='");
out.write(style);
out.write("'>");
out.write(msg.getSummary());
out.write(" - ");
out.write(Utils.encode(msg.getDetail()));
out.write("</span>");
out.write("</td><td>");
// Next Message icon image - clicking shows next message
String rightValue = getClientId(context) + NamingContainer.SEPARATOR_CHAR + Integer.toString(ACTION_NEXT);
String rightOnclick = Utils.generateFormSubmit(context, this, field, rightValue);
out.write(Utils.buildImageTag(context, WebResources.IMAGE_MOVERIGHT, 12, 12, null, rightOnclick, "absmiddle"));
out.write("</td></tr></table>");
if (panel != null)
{
PanelGenerator.generatePanelEnd(out,
context.getExternalContext().getRequestContextPath(),
panel);
}
}
/**
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = getHiddenFieldName();
String value = (String)requestMap.get(fieldId);
// we encoded the value to start with our Id
if (value != null && value.startsWith(getClientId(context)))
{
// we were clicked, strip out the value
int action = Integer.parseInt(value.substring(getClientId(context).length() + 1));
// raise an event to represent the requested action
MessageEvent event = new MessageEvent(this, action);
queueEvent(event);
}
}
/**
* @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof MessageEvent)
{
switch (((MessageEvent)event).Action)
{
case ACTION_NEXT:
currentMessage++;
if (currentMessage >= this.messages.size())
{
currentMessage = 0;
}
break;
case ACTION_PREVIOUS:
currentMessage--;
if (currentMessage < 0)
{
currentMessage = this.messages.size() - 1;
}
break;
}
}
else
{
super.broadcast(event);
}
}
/**
* @return Returns the bgcolor.
*/
public String getBgcolor()
{
ValueBinding vb = getValueBinding("bgcolor");
if (vb != null)
{
this.bgcolor = (String)vb.getValue(getFacesContext());
}
return this.bgcolor;
}
/**
* @param bgcolor The bgcolor to set.
*/
public void setBgcolor(String bgcolor)
{
this.bgcolor = bgcolor;
}
/**
* @return Returns the border name.
*/
public String getBorder()
{
ValueBinding vb = getValueBinding("border");
if (vb != null)
{
this.border = (String)vb.getValue(getFacesContext());
}
return this.border;
}
/**
* @param border The border name to user.
*/
public void setBorder(String border)
{
this.border = border;
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* We use a hidden field name based on the parent form component Id and
* the string "status" to give a hidden field name that can be shared by all status messages
* within a single UIForm component.
*
* @return hidden field name
*/
private String getHiddenFieldName()
{
UIForm form = Utils.getParentForm(getFacesContext(), this);
return form.getClientId(getFacesContext()) + NamingContainer.SEPARATOR_CHAR + "status";
}
// ------------------------------------------------------------------------------
// Private members
public static final String STATUS_MESSAGE = "status-message";
private final static String CSS_INFO = "statusInfoText";
private final static String CSS_WARNING = "statusWarningText";
private final static String CSS_ERROR = "statusErrorText";
private final static int ACTION_PREVIOUS = 0;
private final static int ACTION_NEXT = 1;
private final static int HISTORY_SIZE = 10;
private final static String MSG_DEFAULT_STATUS = "status_message_default";
private List<FacesMessage> messages = new LinkedList<FacesMessage>();
private int currentMessage = 0;
// component settings
private String border = null;
private String bgcolor = null;
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the an action that occurs when the previous/next buttons are clicked.
*/
public static class MessageEvent extends ActionEvent
{
public MessageEvent(UIComponent component, int action)
{
super(component);
Action = action;
}
public int Action;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.data;
/**
* @author kevinr
*/
public class GridArrayDataModel implements IGridDataModel
{
/**
* Constructor
*
* @param data Array of Object (beans) row data
*/
public GridArrayDataModel(Object[] data)
{
this.data = data;
}
/**
* Get a row object for the specified row index
*
* @param index valid row index
*
* @return row object for the specified index
*/
public Object getRow(int index)
{
return this.data[index];
}
/**
* Return the number of rows in the data model
*
* @return row count
*/
public int size()
{
return this.data.length;
}
/**
* Sort the data set using the specified sort parameters
*
* @param column Column to sort
* @param descending True for descending sort, false for ascending
* @param mode Sort mode to use (see IDataContainer constants)
*/
public void sort(String column, boolean descending, String mode)
{
}
private Object[] data = null;
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.data;
import java.util.List;
import org.alfresco.web.data.QuickSort;
/**
* @author kevinr
*/
public class GridListDataModel implements IGridDataModel
{
/**
* Constructor
*
* @param data List of Object[] row data
*/
public GridListDataModel(List data)
{
this.data = data;
}
/**
* Get a row object for the specified row index
*
* @param index valid row index
*
* @return row object for the specified index
*/
public Object getRow(int index)
{
return this.data.get(index);
}
/**
* Return the number of rows in the data model
*
* @return row count
*/
public int size()
{
return this.data.size();
}
/**
* Sort the data set using the specified sort parameters
*
* @param column Column to sort
* @param descending True for descending sort, false for ascending
* @param mode Sort mode to use (see IDataContainer constants)
*/
public void sort(String column, boolean descending, String mode)
{
try
{
QuickSort sorter = new QuickSort(this.data, column, !descending, mode);
sorter.sort();
}
catch (Exception err)
{
throw new RuntimeException("Failed to sort data: " + err.getMessage(), err);
}
}
private List data = null;
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.data;
/**
* @author kevinr
*/
public interface IGridDataModel
{
/**
* Get a row object for the specified row index
*
* @param index valid row index
*
* @return row object for the specified index
*/
public Object getRow(int index);
/**
* Return the number of rows in the data model
*
* @return row count
*/
public int size();
/**
* Sort the data set using the specified sort parameters
*
* @param column Column to sort
* @param descending True for descending sort, false for ascending
* @param mode Sort mode to use (see IDataContainer constants)
*/
public void sort(String column, boolean descending, String mode);
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.data;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
/**
* @author Kevin Roast
*/
public class UIColumn extends UIComponentBase
{
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Data";
}
/**
* Return the UI Component to be used as the header for this column
*
* @return UIComponent
*/
public UIComponent getHeader()
{
return getFacet("header");
}
/**
* Return the UI Component to be used as the footer for this column
*
* @return UIComponent
*/
public UIComponent getFooter()
{
return getFacet("footer");
}
/**
* Return the UI Component to be used as the large icon for this column
*
* @return UIComponent
*/
public UIComponent getLargeIcon()
{
return getFacet("large-icon");
}
/**
* Return the UI Component to be used as the small icon for this column
*
* @return UIComponent
*/
public UIComponent getSmallIcon()
{
return getFacet("small-icon");
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.primary = ((Boolean)values[1]).booleanValue();
this.actions = ((Boolean)values[2]).booleanValue();
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[3];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = (this.primary ? Boolean.TRUE : Boolean.FALSE);
values[2] = (this.actions ? Boolean.TRUE : Boolean.FALSE);
return (values);
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* @return true if this is the primary column
*/
public boolean getPrimary()
{
ValueBinding vb = getValueBinding("primary");
if (vb != null)
{
this.primary = (Boolean)vb.getValue(getFacesContext());
}
return this.primary;
}
/**
* @param primary True if this is the primary column, false otherwise
*/
public void setPrimary(boolean primary)
{
this.primary = primary;
}
/**
* @return true if this is the column containing actions for the current row
*/
public boolean getActions()
{
ValueBinding vb = getValueBinding("actions");
if (vb != null)
{
this.actions = (Boolean)vb.getValue(getFacesContext());
}
return this.actions;
}
/**
* @param actions True if this is the column containing actions for the current row
*/
public void setActions(boolean actions)
{
this.actions = actions;
}
// ------------------------------------------------------------------------------
// Private data
private boolean primary = false;
private boolean actions = false;
}

View File

@@ -0,0 +1,339 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.data;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.component.NamingContainer;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import org.apache.log4j.Logger;
import org.alfresco.web.app.Application;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.WebResources;
/**
* @author Kevin Roast
*/
public class UIDataPager extends UICommand
{
private static Logger s_logger = Logger.getLogger(IDataContainer.class);
private static final String LAST_PAGE = "last_page";
private static final String NEXT_PAGE = "next_page";
private static final String PREVIOUS_PAGE = "prev_page";
private static final String FIRST_PAGE = "first_page";
private static final String MSG_PAGEINFO = "page_info";
// ------------------------------------------------------------------------------
// Construction
/**
* Default constructor
*/
public UIDataPager()
{
setRendererType(null);
}
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
IDataContainer dataContainer = getDataContainer();
if (dataContainer == null)
{
throw new IllegalStateException("Must nest UISortLink inside component implementing IDataContainer!");
}
// this component will only render itself if the parent DataContainer is setup
// with a valid "pageSize" property
if (isRendered() == false || dataContainer.getPageSize() == -1)
{
return;
}
ResponseWriter out = context.getResponseWriter();
ResourceBundle bundle = Application.getBundle(context);
StringBuilder buf = new StringBuilder(512);
int currentPage = dataContainer.getCurrentPage();
int pageCount = dataContainer.getPageCount();
buf.append("<span");
if (getAttributes().get("style") != null)
{
buf.append(" style=\"")
.append(getAttributes().get("style"))
.append('"');
}
if (getAttributes().get("styleClass") != null)
{
buf.append(" class=")
.append(getAttributes().get("styleClass"));
}
buf.append('>');
// output Page X of Y text
buf.append(MessageFormat.format(bundle.getString(MSG_PAGEINFO), new Object[] {
Integer.toString(currentPage + 1), // current page can be zero if no data present
Integer.toString(pageCount)
}));
buf.append("&nbsp;");
// output HTML links or labels to render the paging controls
// first page
if (currentPage != 0)
{
buf.append("<a href='#' onclick=\"");
buf.append(generateEventScript(0));
buf.append("\">");
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_FIRSTPAGE, 16, 16, bundle.getString(FIRST_PAGE)));
buf.append("</a>");
}
else
{
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_FIRSTPAGE_NONE, 16, 16, null));
}
// previous page
if (currentPage != 0)
{
buf.append("<a href='#' onclick=\"");
buf.append(generateEventScript(currentPage - 1));
buf.append("\">");
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_PREVIOUSPAGE, 16, 16, bundle.getString(PREVIOUS_PAGE)));
buf.append("</a>");
}
else
{
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_PREVIOUSPAGE_NONE, 16, 16, null));
}
buf.append("&nbsp;");
// clickable digits for pages 1 to 10
int totalIndex = (pageCount < 10 ? pageCount : 10);
for (int i=0; i<totalIndex; i++)
{
if (i != currentPage)
{
buf.append("<a href='#' onclick=\"")
.append(generateEventScript(i))
.append("\">")
.append(i + 1)
.append("</a>&nbsp;");
}
else
{
buf.append("<b>")
.append(i + 1)
.append("</b>&nbsp;");
}
}
// clickable digits for pages 20 to 100 (in jumps of 10)
if (pageCount >= 20)
{
buf.append("...&nbsp;");
totalIndex = (pageCount / 10) * 10;
totalIndex = (totalIndex < 100 ? totalIndex : 100);
for (int i=19; i<totalIndex; i += 10)
{
if (i != currentPage)
{
buf.append("<a href='#' onclick=\"")
.append(generateEventScript(i))
.append("\">")
.append(i + 1)
.append("</a>&nbsp;");
}
else
{
buf.append("<b>")
.append(i + 1)
.append("</b>&nbsp;");
}
}
}
// clickable digits for last page if > 10 and not already shown
if ((pageCount > 10) && (pageCount % 10 != 0))
{
if (pageCount-1 != currentPage)
{
if (pageCount < 20)
{
buf.append("...&nbsp;");
}
buf.append("<a href='#' onclick=\"")
.append(generateEventScript(pageCount-1))
.append("\">")
.append(pageCount)
.append("</a>&nbsp;");
}
else
{
if (pageCount < 20)
{
buf.append("...&nbsp;");
}
buf.append("<b>")
.append(pageCount)
.append("</b>&nbsp;");
}
}
// next page
if ((dataContainer.getCurrentPage() < dataContainer.getPageCount() - 1) == true)
{
buf.append("<a href='#' onclick=\"");
buf.append(generateEventScript(currentPage + 1));
buf.append("\">");
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_NEXTPAGE, 16, 16, bundle.getString(NEXT_PAGE)));
buf.append("</a>");
}
else
{
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_NEXTPAGE_NONE, 16, 16, null));
}
// last page
if ((dataContainer.getCurrentPage() < dataContainer.getPageCount() - 1) == true)
{
buf.append("<a href='#' onclick=\"");
buf.append(generateEventScript(dataContainer.getPageCount() - 1));
buf.append("\">");
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_LASTPAGE, 16, 16, bundle.getString(LAST_PAGE)));
buf.append("</a>");
}
else
{
buf.append(Utils.buildImageTag(context, WebResources.IMAGE_LASTPAGE_NONE, 16, 16, null));
}
buf.append("</span>");
out.write(buf.toString());
}
/**
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = getHiddenFieldName();
String value = (String)requestMap.get(fieldId);
if (value != null && value.length() != 0)
{
// we were clicked - queue an event to represent the click
// cannot handle the event here as other components etc. have not had
// a chance to decode() - we queue an event to be processed later
PageEvent actionEvent = new PageEvent(this, Integer.valueOf(value).intValue());
this.queueEvent(actionEvent);
}
}
/**
* @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof PageEvent == false)
{
// let the super class handle events which we know nothing about
super.broadcast(event);
}
else
{
// found a sort event for us!
if (s_logger.isDebugEnabled())
s_logger.debug("Handling paging event to index: " + ((PageEvent)event).Page);
getDataContainer().setCurrentPage(((PageEvent)event).Page);
}
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* Return the parent data container for this component
*/
private IDataContainer getDataContainer()
{
return Utils.getParentDataContainer(getFacesContext(), this);
}
/**
* Output the JavaScript event script to jump to a specified page
*
* @param page page index to generate script to jump too
*/
private String generateEventScript(int page)
{
return Utils.generateFormSubmit(getFacesContext(), this, getHiddenFieldName(), Integer.toString(page));
}
/**
* We use a hidden field name based on the parent data container component Id and
* the string "pager" to give a field name that can be shared by all pager links
* within a single data container component.
*
* @return hidden field name
*/
private String getHiddenFieldName()
{
UIComponent dataContainer = (UIComponent)Utils.getParentDataContainer(getFacesContext(), this);
return dataContainer.getClientId(getFacesContext()) + NamingContainer.SEPARATOR_CHAR + "pager";
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the clicking of a sortable column.
*/
private static class PageEvent extends ActionEvent
{
public PageEvent(UIComponent component, int page)
{
super(component);
Page = page;
}
public int Page = 0;
}
}

View File

@@ -0,0 +1,538 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.data;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigService;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.ui.common.renderer.data.IRichListRenderer;
import org.alfresco.web.ui.common.renderer.data.RichListRenderer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.jsf.FacesContextUtils;
/**
* @author Kevin Roast
*/
public class UIRichList extends UIComponentBase implements IDataContainer
{
// ------------------------------------------------------------------------------
// Construction
/**
* Default constructor
*/
public UIRichList()
{
setRendererType("org.alfresco.faces.RichListRenderer");
IRichListRenderer test = new RichListRenderer.IconViewRenderer();
// get the list of views from the client configuration
ConfigService configSvc = (ConfigService)FacesContextUtils.getRequiredWebApplicationContext(
FacesContext.getCurrentInstance()).getBean(Application.BEAN_CONFIG_SERVICE);
ClientConfigElement clientConfig = (ClientConfigElement)configSvc.getGlobalConfig().
getConfigElement(ClientConfigElement.CONFIG_ELEMENT_ID);
List<String> views = clientConfig.getViews();
// instantiate each renderer and add to the list
for (String view : views)
{
try
{
Class clazz = Class.forName(view);
IRichListRenderer renderer = (IRichListRenderer)clazz.newInstance();
UIRichList.viewRenderers.put(renderer.getViewModeID(), renderer);
if (logger.isDebugEnabled())
logger.debug("Added view '" + renderer.getViewModeID() +
"' to UIRichList");
}
catch (Exception e)
{
if (logger.isWarnEnabled())
{
logger.warn("Failed to create renderer: " + view, e);
}
}
}
}
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Data";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.currentPage = ((Integer)values[1]).intValue();
this.sortColumn = (String)values[2];
this.sortDescending = ((Boolean)values[3]).booleanValue();
this.value = values[4]; // not serializable!
this.dataModel = (IGridDataModel)values[5]; // not serializable!
this.viewMode = (String)values[6];
this.pageSize = ((Integer)values[7]).intValue();
this.initialSortColumn = (String)values[8];
this.initialSortDescending = ((Boolean)values[9]).booleanValue();
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[10];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = Integer.valueOf(this.currentPage);
values[2] = this.sortColumn;
values[3] = (this.sortDescending ? Boolean.TRUE : Boolean.FALSE);
values[4] = this.value;
values[5] = this.dataModel;
values[6] = this.viewMode;
values[7] = Integer.valueOf(this.pageSize);
values[8] = this.initialSortColumn;
values[9] = (this.initialSortDescending ? Boolean.TRUE : Boolean.FALSE);
return (values);
}
/**
* Get the value (for this component the value is an object used as the DataModel)
*
* @return the value
*/
public Object getValue()
{
if (this.value == null)
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.value = vb.getValue(getFacesContext());
}
}
return this.value;
}
/**
* Set the value (for this component the value is an object used as the DataModel)
*
* @param value the value
*/
public void setValue(Object value)
{
this.dataModel = null;
this.value = value;
}
/**
* Clear the current sorting settings back to the defaults
*/
public void clearSort()
{
this.sortColumn = null;
this.sortDescending = true;
this.initialSortColumn = null;
this.initialSortDescending = false;
}
/**
* Get the view mode for this Rich List
*
* @return view mode as a String
*/
public String getViewMode()
{
ValueBinding vb = getValueBinding("viewMode");
if (vb != null)
{
this.viewMode = (String)vb.getValue(getFacesContext());
}
return this.viewMode;
}
/**
* Set the current view mode for this Rich List
*
* @param viewMode the view mode as a String
*/
public void setViewMode(String viewMode)
{
this.viewMode = viewMode;
}
/**
* Return the UI Component to be used as the "no items available" message
*
* @return UIComponent
*/
public UIComponent getEmptyMessage()
{
return getFacet("empty");
}
// ------------------------------------------------------------------------------
// IDataContainer implementation
/**
* Return the currently sorted column if any
*
* @return current sorted column if any
*/
public String getCurrentSortColumn()
{
return this.sortColumn;
}
/**
* @see org.alfresco.web.data.IDataContainer#isCurrentSortDescending()
*/
public boolean isCurrentSortDescending()
{
return this.sortDescending;
}
/**
* @return Returns the initialSortColumn.
*/
public String getInitialSortColumn()
{
return this.initialSortColumn;
}
/**
* @param initialSortColumn The initialSortColumn to set.
*/
public void setInitialSortColumn(String initialSortColumn)
{
this.initialSortColumn = initialSortColumn;
}
/**
* @return Returns the initialSortDescending.
*/
public boolean isInitialSortDescending()
{
return this.initialSortDescending;
}
/**
* @param initialSortDescending The initialSortDescending to set.
*/
public void setInitialSortDescending(boolean initialSortDescending)
{
this.initialSortDescending = initialSortDescending;
}
/**
* Returns the current page size used for this list, or -1 for no paging.
*/
public int getPageSize()
{
ValueBinding vb = getValueBinding("pageSize");
if (vb != null)
{
int pageSize = ((Integer)vb.getValue(getFacesContext())).intValue();
if (pageSize != this.pageSize)
{
// force a reset of the current page - else the bind may show a page that isn't there
setPageSize(pageSize);
}
}
return this.pageSize;
}
/**
* Sets the current page size used for the list.
*
* @param val
*/
public void setPageSize(int val)
{
if (val >= -1)
{
this.pageSize = val;
setCurrentPage(0);
}
}
/**
* @see org.alfresco.web.data.IDataContainer#getPageCount()
*/
public int getPageCount()
{
return this.pageCount;
}
/**
* Return the current page the list is displaying
*
* @return current page zero based index
*/
public int getCurrentPage()
{
return this.currentPage;
}
/**
* @see org.alfresco.web.data.IDataContainer#setCurrentPage(int)
*/
public void setCurrentPage(int index)
{
this.currentPage = index;
}
/**
* Returns true if a row of data is available
*
* @return true if data is available, false otherwise
*/
public boolean isDataAvailable()
{
return this.rowIndex < this.maxRowIndex;
}
/**
* Returns the next row of data from the data model
*
* @return next row of data as a Bean object
*/
public Object nextRow()
{
// get next row and increment row count
Object rowData = getDataModel().getRow(this.rowIndex + 1);
// Prepare the data-binding variable "var" ready for the next cycle of
// renderering for the child components.
String var = (String)getAttributes().get("var");
if (var != null)
{
Map requestMap = getFacesContext().getExternalContext().getRequestMap();
if (isDataAvailable() == true)
{
requestMap.put(var, rowData);
}
else
{
requestMap.remove(var);
}
}
this.rowIndex++;
return rowData;
}
/**
* Sort the dataset using the specified sort parameters
*
* @param column Column to sort
* @param descending True for descending sort, false for ascending
* @param mode Sort mode to use (see IDataContainer constants)
*/
public void sort(String column, boolean descending, String mode)
{
this.sortColumn = column;
this.sortDescending = descending;
// delegate to the data model to sort its contents
// place in a UserTransaction as we may need to perform a LOT of node calls to complete
UserTransaction tx = null;
try
{
if (getDataModel().size() > 64)
{
FacesContext context = FacesContext.getCurrentInstance();
tx = Repository.getUserTransaction(context, true);
tx.begin();
}
getDataModel().sort(column, descending, mode);
// commit the transaction
if (tx != null)
{
tx.commit();
}
}
catch (Exception err)
{
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
}
}
// ------------------------------------------------------------------------------
// UIRichList implementation
/**
* Method called to bind the RichList component state to the data model value
*/
public void bind()
{
int rowCount = getDataModel().size();
// if a page size is specified, then we use that
int pageSize = getPageSize();
if (pageSize != -1)
{
// calc start row index based on current page index
this.rowIndex = (this.currentPage * pageSize) - 1;
// calc total number of pages available
this.pageCount = (rowCount / this.pageSize) + 1;
if (rowCount % pageSize == 0 && this.pageCount != 1)
{
this.pageCount--;
}
// calc the maximum row index that can be returned
this.maxRowIndex = this.rowIndex + pageSize;
if (this.maxRowIndex >= rowCount)
{
this.maxRowIndex = rowCount - 1;
}
}
// else we are not paged so show all data from start
else
{
this.rowIndex = -1;
this.pageCount = 1;
this.maxRowIndex = (rowCount - 1);
}
if (logger.isDebugEnabled())
logger.debug("Bound datasource: PageSize: " + pageSize + "; CurrentPage: " + this.currentPage + "; RowIndex: " + this.rowIndex + "; MaxRowIndex: " + this.maxRowIndex + "; RowCount: " + rowCount);
}
/**
* @return A new IRichListRenderer implementation for the current view mode
*/
public IRichListRenderer getViewRenderer()
{
// get type from current view mode, then create an instance of the renderer
IRichListRenderer renderer = null;
if (getViewMode() != null)
{
renderer = (IRichListRenderer)UIRichList.viewRenderers.get(getViewMode());
}
return renderer;
}
/**
* Return the data model wrapper
*
* @return IGridDataModel
*/
private IGridDataModel getDataModel()
{
if (this.dataModel == null)
{
// build the appropriate data-model wrapper object
Object val = getValue();
if (val instanceof List)
{
this.dataModel = new GridListDataModel((List)val);
}
else if ( (java.lang.Object[].class).isAssignableFrom(val.getClass()) )
{
this.dataModel = new GridArrayDataModel((Object[])val);
}
else
{
throw new IllegalStateException("UIRichList 'value' attribute binding should specify data model of a supported type!");
}
// sort first time on initially sorted column if set
if (this.sortColumn == null)
{
String initialSortColumn = getInitialSortColumn();
if (initialSortColumn != null && initialSortColumn.length() != 0)
{
boolean descending = isInitialSortDescending();
// TODO: add support for retrieving correct column sort mode here
this.sortColumn = initialSortColumn;
this.sortDescending = descending;
}
}
if (this.sortColumn != null)
{
// delegate to the data model to sort its contents
this.dataModel.sort(this.sortColumn, this.sortDescending, IDataContainer.SORT_CASEINSENSITIVE);
}
// reset current page
this.currentPage = 0;
}
return this.dataModel;
}
// ------------------------------------------------------------------------------
// Private data
/** map of available IRichListRenderer instances */
private final static Map<String, IRichListRenderer> viewRenderers = new HashMap<String, IRichListRenderer>(5);
// component state
private int currentPage = 0;
private String sortColumn = null;
private boolean sortDescending = true;
private Object value = null;
private IGridDataModel dataModel = null;
private String viewMode = null;
private int pageSize = -1;
private String initialSortColumn = null;
private boolean initialSortDescending = false;
// transient component state that exists during a single page refresh only
private int rowIndex = -1;
private int maxRowIndex = -1;
private int pageCount = 1;
private static Log logger = LogFactory.getLog(IDataContainer.class);
}

View File

@@ -0,0 +1,342 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.data;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.NamingContainer;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import org.apache.log4j.Logger;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.WebResources;
/**
* @author Kevin Roast
*/
public class UISortLink extends UICommand
{
/**
* Default Constructor
*/
public UISortLink()
{
setRendererType(null);
}
/**
* @see javax.faces.component.UIComponent#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
ResponseWriter out = context.getResponseWriter();
IDataContainer dataContainer = getDataContainer();
if (dataContainer == null)
{
throw new IllegalStateException("Must nest UISortLink inside component implementing IDataContainer!");
}
// swap sort direction if we were last sorted column
boolean bPreviouslySorted = false;
boolean descending = true;
String lastSortedColumn = dataContainer.getCurrentSortColumn();
if (lastSortedColumn == (String)getValue())
{
descending = !dataContainer.isCurrentSortDescending();
bPreviouslySorted = true;
}
// render sort link
StringBuilder buf = new StringBuilder(256);
buf.append("<nobr><a href='#' onclick=\"");
// generate some JavaScript to set a hidden form field and submit
// a form which request attributes that we can decode
buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(context), getClientId(context)));
buf.append('"');
if (getAttributes().get("style") != null)
{
buf.append(" style=\"")
.append(getAttributes().get("style"))
.append('"');
}
if (getAttributes().get("styleClass") != null)
{
buf.append(" class=")
.append(getAttributes().get("styleClass"));
}
if (getAttributes().get("tooltip") != null)
{
buf.append(" title=\"")
.append(getAttributes().get("tooltip"))
.append('"');
}
buf.append('>');
// output column label
buf.append((String)getAttributes().get("label"));
if (bPreviouslySorted == true)
{
if (descending == true)
{
buf.append(" ")
.append(Utils.buildImageTag(context, WebResources.IMAGE_SORTUP, 10, 6, null));
}
else
{
buf.append(" ")
.append(Utils.buildImageTag(context, WebResources.IMAGE_SORTDOWN, 10, 6, null));
}
}
else
{
buf.append(" ")
.append(Utils.buildImageTag(context, WebResources.IMAGE_SORTNONE, 10, 7, null));
}
buf.append("</a></nobr>");
out.write(buf.toString());
}
/**
* @see javax.faces.component.UIComponent#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = getHiddenFieldName(context);
String value = (String)requestMap.get(fieldId);
if (value != null && value.equals(getClientId(context)))
{
// we were clicked - queue an event to represent the click
// cannot handle the event here as other components etc. have not had
// a chance to decode() - we queue an event to be processed later
SortEvent actionEvent = new SortEvent(this, (String)this.getValue());
this.queueEvent(actionEvent);
}
}
/**
* @see javax.faces.component.UIComponent#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof SortEvent == false)
{
// let the super class handle events which we know nothing about
super.broadcast(event);
}
else if ( ((SortEvent)event).Column.equals(getColumn()) )
{
// found a sort event for us!
if (s_logger.isDebugEnabled())
s_logger.debug("Handling sort event for column: " + ((SortEvent)event).Column);
if (getColumn().equals(getDataContainer().getCurrentSortColumn()) == true)
{
// reverse sort direction
this.descending = !this.descending;
}
else
{
// revert to default sort direction
this.descending = true;
}
getDataContainer().sort(getColumn(), this.descending, getMode());
}
}
/**
* We use a hidden field name based on the parent data container component Id and
* the string "sort" to give a field name that can be shared by all sort links
* within a single data container component.
*
* @param context FacesContext
*
* @return hidden field name
*/
private String getHiddenFieldName(FacesContext context)
{
UIComponent dataContainer = (UIComponent)Utils.getParentDataContainer(context, this);
return dataContainer.getClientId(context) + NamingContainer.SEPARATOR_CHAR + "sort";
}
/**
* Column name referenced by this link
*
* @return column name
*/
public String getColumn()
{
return (String)getValue();
}
/**
* Sorting mode - see IDataContainer constants
*
* @return sorting mode - see IDataContainer constants
*/
public String getMode()
{
return this.mode;
}
/**
* Set the sorting mode - see IDataContainer constants
*
* @param sortMode the sorting mode- see IDataContainer constants
*/
public void setMode(String sortMode)
{
this.mode = sortMode;
}
/**
* Returns true for descending sort, false for ascending
*
* @return true for descending sort, false for ascending
*/
public boolean isDescending()
{
return this.descending;
}
/**
* @return Returns the label.
*/
public String getLabel()
{
ValueBinding vb = getValueBinding("label");
if (vb != null)
{
this.label = (String)vb.getValue(getFacesContext());
}
return this.label;
}
/**
* @param label The label to set.
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* @return Returns the tooltip.
*/
public String getTooltip()
{
ValueBinding vb = getValueBinding("tooltip");
if (vb != null)
{
this.tooltip = (String)vb.getValue(getFacesContext());
}
return this.tooltip;
}
/**
* @param tooltip The tooltip to set.
*/
public void setTooltip(String tooltip)
{
this.tooltip = tooltip;
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.descending = ((Boolean)values[1]).booleanValue();
this.mode = (String)values[2];
this.label = (String)values[3];
this.tooltip = (String)values[4];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[5];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = (this.descending ? Boolean.TRUE : Boolean.FALSE);
values[2] = this.mode;
values[3] = this.label;
values[4] = this.tooltip;
return values;
}
/**
* Return the parent data container for this component
*/
private IDataContainer getDataContainer()
{
return Utils.getParentDataContainer(getFacesContext(), this);
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the clicking of a sortable column.
*/
private static class SortEvent extends ActionEvent
{
public SortEvent(UIComponent component, String column)
{
super(component);
Column = column;
}
public String Column = null;
}
// ------------------------------------------------------------------------------
// Constants
private static Logger s_logger = Logger.getLogger(IDataContainer.class);
/** sorting mode */
private String mode = IDataContainer.SORT_CASEINSENSITIVE;
private String label;
private String tooltip;
/** true for descending sort, false for ascending */
private boolean descending = false;
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.debug;
import java.io.IOException;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
/**
* Base class for all debug components
*
* @author gavinc
*/
public abstract class BaseDebugComponent extends SelfRenderingComponent
{
private String title;
/**
* Retrieves the debug data to show for the component as a Map
*
* @return The Map of data
*/
public abstract Map getDebugData();
/**
* @see javax.faces.component.UIComponent#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
out.write("<table cellpadding='3' cellspacing='3' border='1'>");
if (this.getTitle() != null)
{
out.write("<tr><td colspan='2'>");
out.write(this.getTitle());
out.write("</td></tr>");
}
out.write("<tr><th align='left'>Property</th><th align='left'>Value</th></tr>");
Map session = getDebugData();
for (Object key : session.keySet())
{
out.write("<tr><td>");
out.write(key.toString());
out.write("</td><td>");
String value = session.get(key).toString();
if (value == null || value.length() == 0)
{
out.write("&nbsp;");
}
else
{
// replace any ; characters with ;<space> as that will help break up long lines
value = value.replaceAll(";", "; ");
out.write(value);
}
out.write("</td></tr>");
}
out.write("</table>");
super.encodeBegin(context);
}
/**
* @see javax.faces.component.UIComponent#getRendersChildren()
*/
public boolean getRendersChildren()
{
return false;
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.title = (String)values[1];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[2];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.title;
return (values);
}
/**
* Returns the title
*
* @return The title
*/
public String getTitle()
{
ValueBinding vb = getValueBinding("title");
if (vb != null)
{
this.title = (String)vb.getValue(getFacesContext());
}
return this.title;
}
/**
* Sets the title
*
* @param title The title
*/
public void setTitle(String title)
{
this.title = title;
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.debug;
import java.util.Map;
import javax.faces.context.FacesContext;
/**
* Component which displays the current state of the HTTP session
*
* @author gavinc
*/
public class UIHttpApplicationState extends BaseDebugComponent
{
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.debug.HttpApplicationState";
}
/**
* @see org.alfresco.web.ui.common.component.debug.BaseDebugComponent#getDebugData()
*/
public Map getDebugData()
{
return FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.debug;
import java.util.Map;
import javax.faces.context.FacesContext;
/**
* Component which displays the headers for the current HTTP request
*
* @author gavinc
*/
public class UIHttpRequestHeaders extends BaseDebugComponent
{
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.debug.HttpRequestHeaders";
}
/**
* @see org.alfresco.web.ui.common.component.debug.BaseDebugComponent#getDebugData()
*/
public Map getDebugData()
{
return FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap();
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.debug;
import java.util.Map;
import javax.faces.context.FacesContext;
/**
* Component which displays the parameters for the current HTTP request
*
* @author gavinc
*/
public class UIHttpRequestParams extends BaseDebugComponent
{
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.debug.HttpRequestParams";
}
/**
* @see org.alfresco.web.ui.common.component.debug.BaseDebugComponent#getDebugData()
*/
public Map getDebugData()
{
return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.debug;
import java.util.Map;
import javax.faces.context.FacesContext;
/**
* Component which displays the current state of the HTTP request
*
* @author gavinc
*/
public class UIHttpRequestState extends BaseDebugComponent
{
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.debug.HttpRequestState";
}
/**
* @see org.alfresco.web.ui.common.component.debug.BaseDebugComponent#getDebugData()
*/
public Map getDebugData()
{
return FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.debug;
import java.util.Map;
import javax.faces.context.FacesContext;
/**
* Component which displays the current state of the HTTP session
*
* @author gavinc
*/
public class UIHttpSessionState extends BaseDebugComponent
{
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.debug.HttpSessionState";
}
/**
* @see org.alfresco.web.ui.common.component.debug.BaseDebugComponent#getDebugData()
*/
public Map getDebugData()
{
return FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.debug;
import java.util.Map;
/**
* Component which displays the system properties of the VM
*
* @author gavinc
*/
public class UISystemProperties extends BaseDebugComponent
{
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.debug.SystemProperties";
}
/**
* @see org.alfresco.web.ui.common.component.debug.BaseDebugComponent#getDebugData()
*/
public Map getDebugData()
{
return System.getProperties();
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.description;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
/**
* Description component that outputs a dynamic description
*
* @author gavinc
*/
public class UIDescription extends SelfRenderingComponent
{
private String controlValue;
private String text;
/**
* @return The control value the description is for
*/
public String getControlValue()
{
if (this.controlValue == null)
{
ValueBinding vb = getValueBinding("controlValue");
if (vb != null)
{
this.controlValue = (String)vb.getValue(getFacesContext());
}
}
return this.controlValue;
}
/**
* @param controlValue Sets the control value this description is for
*/
public void setControlValue(String controlValue)
{
this.controlValue = controlValue;
}
/**
* @return Returns the description text
*/
public String getText()
{
if (this.text == null)
{
ValueBinding vb = getValueBinding("text");
if (vb != null)
{
this.text = (String)vb.getValue(getFacesContext());
}
}
return this.text;
}
/**
* @param text Sets the description text
*/
public void setText(String text)
{
this.text = text;
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Description";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.controlValue = (String)values[1];
this.text = (String)values[2];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[3];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.controlValue;
values[2] = this.text;
return (values);
}
/**
* @see javax.faces.component.UIComponent#getRendersChildren()
*/
public boolean getRendersChildren()
{
return false;
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.description;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
/**
* Descriptions component that outputs descriptions held in a backing object
*
* @author gavinc
*/
public class UIDescriptions extends SelfRenderingComponent
{
private Object value;
/**
* @return Returns the object holding the decriptions
*/
public Object getValue()
{
if (this.value == null)
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.value = vb.getValue(getFacesContext());
}
}
return this.value;
}
/**
* @param value Sets the object holding the description
*/
public void setValue(Object value)
{
this.value = value;
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.Descriptions";
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.value = values[1];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[2];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.value;
return (values);
}
}

View File

@@ -0,0 +1,268 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.description;
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 javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Dynamic description component that switches text based on the events
* of another input control
*
* @author gavinc
*/
public class UIDynamicDescription extends SelfRenderingComponent
{
private static Log logger = LogFactory.getLog(UIDynamicDescription.class);
private String selected;
private String functionName;
/**
* @return The id of the selected description
*/
public String getSelected()
{
if (this.selected == null)
{
ValueBinding vb = getValueBinding("selected");
if (vb != null)
{
this.selected = (String)vb.getValue(getFacesContext());
}
}
return this.selected;
}
/**
* @param selected The id of the selected
*/
public void setSelected(String selected)
{
this.selected = selected;
}
/**
* @return Returns the JavaScript function name to use
*/
public String getFunctionName()
{
if (this.functionName == null)
{
this.functionName = "itemSelected";
}
return this.functionName;
}
/**
* @param functionName Sets the name of the JavaScript function to use
*/
public void setFunctionName(String functionName)
{
this.functionName = functionName;
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.DynamicDescription";
}
/**
* @see javax.faces.component.UIComponent#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (this.isRendered() == false)
{
return;
}
// output the required JavaScript
ResponseWriter out = context.getResponseWriter();
out.write("<script language='JavaScript'>\n");
out.write("var m_");
out.write(getFunctionName());
out.write(" = '");
if (getSelected() != null)
{
out.write("desc-");
out.write(getSelected());
}
out.write("';\n");
out.write("function ");
out.write(getFunctionName());
out.write("(inputControl) {\n");
out.write("if (m_");
out.write(getFunctionName());
out.write(" != '') {\n");
out.write(" document.getElementById(m_");
out.write(getFunctionName());
out.write(").style.display = 'none';\n");
out.write("}\nm_");
out.write(getFunctionName());
out.write(" = 'desc-' + inputControl.value;\n");
out.write("document.getElementById(m_");
out.write(getFunctionName());
out.write(").style.display = 'inline';\n");
out.write("} </script>\n");
}
/**
* @see javax.faces.component.UIComponent#encodeChildren(javax.faces.context.FacesContext)
*/
public void encodeChildren(FacesContext context) throws IOException
{
if (this.isRendered() == false)
{
return;
}
List<UIComponent> kids = getChildren();
for (UIComponent child : kids)
{
if (child instanceof UIDescription)
{
// render the single description
renderDescription(context, ((UIDescription)child).getControlValue(),
((UIDescription)child).getText());
}
else if (child instanceof UIDescriptions)
{
// retrieve the object being pointed to and get
// the descriptions from that
renderDescriptions(context, (UIDescriptions)child);
}
}
}
/**
* @see javax.faces.component.UIComponent#encodeEnd(javax.faces.context.FacesContext)
*/
public void encodeEnd(FacesContext context) throws IOException
{
// don't need to do anything
}
/**
* @see javax.faces.component.UIComponent#getRendersChildren()
*/
public boolean getRendersChildren()
{
return true;
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.selected = (String)values[1];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[2];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.selected;
return (values);
}
/**
* Renders a description item
*
* @param context The faces context
* @param controlId The id of the control the description is for
* @param test The description text
*/
private void renderDescription(FacesContext context, String controlId, String text)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
out.write("<span");
String spanId = "desc-" + controlId;
outputAttribute(out, spanId, "id");
if (controlId.equals(this.selected))
{
outputAttribute(out, "display: inline", "style");
}
else
{
outputAttribute(out, "display: none", "style");
}
out.write(">");
out.write(Utils.encode(text));
out.write("</span>\n");
}
/**
* Renders the given descriptions component
*
* @param context The faces context
* @param descriptions The descriptions to render
*/
private void renderDescriptions(FacesContext context, UIDescriptions descriptions)
throws IOException
{
// get hold of the object holding the descriptions and make sure
// it is of the correct type
Object obj = descriptions.getValue();
if (obj instanceof Map)
{
Map<String, String> items = (Map)obj;
for (String id : items.keySet())
{
renderDescription(context, id, items.get(id));
}
}
else if (obj instanceof List)
{
Iterator iter = ((List)obj).iterator();
while (iter.hasNext())
{
UIDescription desc = (UIDescription)iter.next();
renderDescription(context, desc.getControlValue(), desc.getText());
}
}
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.evaluator;
import java.io.IOException;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import org.apache.log4j.Logger;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
/**
* @author kevinr
*/
public abstract class BaseEvaluator extends SelfRenderingComponent
{
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public final String getFamily()
{
return "org.alfresco.faces.evaluators";
}
/**
* @see javax.faces.component.UIComponentBase#getRendersChildren()
*/
public final boolean getRendersChildren()
{
return !evaluate();
}
/**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
*/
public final void encodeBegin(FacesContext context) throws IOException
{
// no output for this component
}
/**
* @see javax.faces.component.UIComponentBase#encodeChildren(javax.faces.context.FacesContext)
*/
public final void encodeChildren(FacesContext context) throws IOException
{
// if this is called, then the evaluate returned false which means
// the child components show not be allowed to render themselves
}
/**
* @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
*/
public final void encodeEnd(FacesContext context) throws IOException
{
// no output for this component
}
/**
* Get the value for this component to be evaluated against
*
* @return the value for this component to be evaluated against
*/
public Object getValue()
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.value = vb.getValue(getFacesContext());
}
return this.value;
}
/**
* Set the value for this component to be evaluated against
*
* @param value the value for this component to be evaluated against
*/
public void setValue(Object value)
{
this.value = value;
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.value = values[1];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[2];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.value;
return (values);
}
/**
* Evaluate against the component attributes. Return true to allow the inner
* components to render, false to hide them during rendering.
*
* @return true to allow rendering of child components, false otherwise
*/
public abstract boolean evaluate();
protected static Logger s_logger = Logger.getLogger(BaseEvaluator.class);
/** the value to be evaluated against */
private Object value;
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.evaluator;
/**
* @author kevinr
*
* Evaluates to true if the value suppied is a boolean string of "true".
*/
public class BooleanEvaluator extends BaseEvaluator
{
/**
* Evaluate against the component attributes. Return true to allow the inner
* components to render, false to hide them during rendering.
*
* @return true to allow rendering of child components, false otherwise
*/
public boolean evaluate()
{
boolean result = false;
try
{
if (getValue() instanceof Boolean)
{
result = ((Boolean)getValue()).booleanValue();
}
else
{
result = Boolean.valueOf((String)getValue()).booleanValue();
}
}
catch (Exception err)
{
// return default value on error
s_logger.debug("Unable to evaluate value to boolean: " + getValue());
}
return result;
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.evaluator;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
/**
* @author kevinr
*
* Evaluates to true if the value exactly matches the supplied string condition.
*/
public class StringEqualsEvaluator extends BaseEvaluator
{
/**
* Evaluate against the component attributes. Return true to allow the inner
* components to render, false to hide them during rendering.
*
* @return true to allow rendering of child components, false otherwise
*/
public boolean evaluate()
{
boolean result = false;
try
{
result = getCondition().equals((String)getValue());
}
catch (Exception err)
{
// return default value on error
s_logger.debug("Expected String value for evaluation: " + getValue());
}
return result;
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.condition = (String)values[1];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[2];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.condition;
return (values);
}
/**
* Get the string condition to match value against
*
* @return the string condition to match value against
*/
public String getCondition()
{
ValueBinding vb = getValueBinding("condition");
if (vb != null)
{
this.condition = (String)vb.getValue(getFacesContext());
}
return this.condition;
}
/**
* Set the string condition to match value against
*
* @param condition string condition to match value against
*/
public void setCondition(String condition)
{
this.condition = condition;
}
/** the string condition to match value against */
private String condition = null;
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.common.component.evaluator;
/**
* @author kevinr
*
* Evaluates to true if the value supplied is not null.
*/
public class ValueSetEvaluator extends BaseEvaluator
{
/**
* Evaluate against the component attributes. Return true to allow the inner
* components to render, false to hide them during rendering.
*
* @return true to allow rendering of child components, false otherwise
*/
public boolean evaluate()
{
return getValue() != null ? true : false;
}
}