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,38 @@
/*
* 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;
/**
* @author Kevin Roast
*/
public final class ComponentConstants
{
public static final String JAVAX_FACES_INPUT = "javax.faces.Input";
public static final String JAVAX_FACES_TEXT = "javax.faces.Text";
public static final String JAVAX_FACES_OUTPUT = "javax.faces.Output";
public static final String JAVAX_FACES_GRID = "javax.faces.Grid";
public static final String JAVAX_FACES_PANEL = "javax.faces.Panel";
public static final String JAVAX_FACES_CHECKBOX = "javax.faces.Checkbox";
public static final String JAVAX_FACES_SELECT_BOOLEAN = "javax.faces.SelectBoolean";
/**
* Private constructor
*/
private ComponentConstants()
{
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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;
import javax.faces.component.StateHolder;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
public class ConstantMethodBinding extends MethodBinding implements StateHolder
{
private String outcome = null;
private boolean transientFlag = false;
public ConstantMethodBinding()
{
}
public ConstantMethodBinding(String yourOutcome)
{
outcome = yourOutcome;
}
public Object invoke(FacesContext context, Object params[])
{
return outcome;
}
public Class getType(FacesContext context)
{
return String.class;
}
public Object saveState(FacesContext context)
{
return outcome;
}
public void restoreState(FacesContext context, Object state)
{
outcome = (String) state;
}
public boolean isTransient()
{
return (this.transientFlag);
}
public void setTransient(boolean transientFlag)
{
this.transientFlag = transientFlag;
}
}

View File

@@ -0,0 +1,188 @@
/*
* 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;
import java.io.IOException;
import java.io.Writer;
/**
* Helper to generate the rounded panel HTML templates
*
* @author kevinr
*/
public final class PanelGenerator
{
public static void generatePanel(Writer out, String contextPath, String panel, String inner)
throws IOException
{
generatePanel(out, contextPath, panel, inner, BGCOLOR_WHITE);
}
public static void generatePanel(Writer out, String contextPath, String panel, String inner, String bgColor)
throws IOException
{
generatePanel(out, contextPath, panel, inner, bgColor, false);
}
public static void generatePanel(Writer out, String contextPath, String panel, String inner, String bgColor, boolean dialog)
throws IOException
{
generatePanelStart(out, contextPath, panel, bgColor, dialog);
out.write(inner);
generatePanelEnd(out, contextPath, panel);
}
public static void generatePanelStart(Writer out, String contextPath, String panel, String bgColor)
throws IOException
{
generatePanelStart(out, contextPath, panel, bgColor, false);
}
public static void generatePanelStart(Writer out, String contextPath, String panel, String bgColor, boolean dialog)
throws IOException
{
out.write("<table cellspacing=0 cellpadding=0 border=0 width=100%><tr><td width=7><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_01.gif' width=7 height=7 alt=''></td>");
out.write("<td background='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_02.gif'><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_02.gif' width=7 height=7 alt=''></td>");
out.write("<td width=7><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_03");
if (dialog)
{
out.write("_squared");
}
out.write(".gif' width=7 height=7 alt=''></td></tr>");
out.write("<tr><td background='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_04.gif'><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_04.gif' width=7 height=7 alt=''></td><td bgcolor='");
out.write(bgColor);
out.write("'>");
}
public static void generatePanelEnd(Writer out, String contextPath, String panel)
throws IOException
{
out.write("</td><td background='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_06.gif'><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_06.gif' width=7 height=7 alt=''></td></tr>");
out.write("<tr><td width=7><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_07.gif' width=7 height=7 alt=''></td>");
out.write("<td background='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_08.gif'><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_08.gif' width=7 height=7 alt=''></td>");
out.write("<td width=7><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(panel);
out.write("_09.gif' width=7 height=7 alt=''></td></tr></table>");
}
public static void generateTitledPanelMiddle(Writer out, String contextPath, String titlePanel,
String contentPanel, String contentBgColor) throws IOException
{
// generate the expanded part, just under the title
out.write("</td><td background='");
out.write(contextPath);
out.write("/images/parts/");
out.write(titlePanel);
out.write("_06.gif'><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(titlePanel);
out.write("_06.gif' width=7 height=7 alt=''></td></tr>");
out.write("<tr><td width=7><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(titlePanel);
out.write("_");
out.write(contentPanel);
out.write("_07.gif' width=7 height=7 alt=''></td>");
out.write("<td background='");
out.write(contextPath);
out.write("/images/parts/");
out.write(titlePanel);
out.write("_08.gif'><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(titlePanel);
out.write("_08.gif' width=7 height=7 alt=''></td>");
out.write("<td width=7><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(titlePanel);
out.write("_");
out.write(contentPanel);
out.write("_09.gif' width=7 height=7 alt=''></td></tr>");
out.write("<tr><td background='");
out.write(contextPath);
out.write("/images/parts/");
out.write(contentPanel);
out.write("_04.gif'><img src='");
out.write(contextPath);
out.write("/images/parts/");
out.write(contentPanel);
out.write("_04.gif' width=7 height=7 alt=''></td><td bgcolor='");
out.write(contentBgColor);
out.write("' style='padding-top:6px;'>");
}
public final static String BGCOLOR_WHITE = "#FFFFFF";
}

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;
import javax.faces.model.SelectItem;
/**
* Wrapper class to facilitate case-insensitive sorting functionality against our SelectItem objects
*
* @author Kevin Roast
*/
public final class SortableSelectItem extends SelectItem implements Comparable
{
public SortableSelectItem(String value, String label, String sort)
{
super(value, label);
this.sort = sort;
}
public int compareTo(Object obj2)
{
if (this.sort == null && obj2 == null) return 0;
if (this.sort == null) return -1;
if (obj2 == null) return 1;
return this.sort.compareToIgnoreCase( ((SortableSelectItem)obj2).sort );
}
private String sort;
}

View File

@@ -0,0 +1,996 @@
/*
* 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;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
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.EvaluationException;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.CIFSServer;
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
import org.alfresco.filesys.smb.server.repo.ContentContext;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.webdav.WebDAVServlet;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.app.servlet.ExternalAccessServlet;
import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.repository.User;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.ui.common.component.UIStatusMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.renderkit.html.HtmlFormRendererBase;
import org.springframework.web.jsf.FacesContextUtils;
/**
* Class containing misc helper methods used by the JSF components.
*
* @author Kevin Roast
*/
public final class Utils
{
private static final String MSG_TIME_PATTERN = "time_pattern";
private static final String MSG_DATE_PATTERN = "date_pattern";
private static final String MSG_DATE_TIME_PATTERN = "date_time_pattern";
private static final String IMAGE_PREFIX16 = "/images/filetypes/";
private static final String IMAGE_PREFIX32 = "/images/filetypes32/";
private static final String IMAGE_POSTFIX = ".gif";
private static final String DEFAULT_FILE_IMAGE16 = IMAGE_PREFIX16 + "_default" + IMAGE_POSTFIX;
private static final String DEFAULT_FILE_IMAGE32 = IMAGE_PREFIX32 + "_default" + IMAGE_POSTFIX;
private static final Map<String, String> s_fileExtensionMap = new HashMap<String, String>(89, 1.0f);
private static Log logger = LogFactory.getLog(Utils.class);
/**
* Private constructor
*/
private Utils()
{
}
/**
* Encodes the given string, so that it can be used within an HTML page.
*
* @param string the String to convert
*/
public static String encode(String string)
{
if (string == null)
{
return "";
}
StringBuilder sb = null; //create on demand
String enc;
char c;
for (int i = 0; i < string.length(); i++)
{
enc = null;
c = string.charAt(i);
switch (c)
{
case '"': enc = "&quot;"; break; //"
case '&': enc = "&amp;"; break; //&
case '<': enc = "&lt;"; break; //<
case '>': enc = "&gt;"; break; //>
//german umlauts
case '\u00E4' : enc = "&auml;"; break;
case '\u00C4' : enc = "&Auml;"; break;
case '\u00F6' : enc = "&ouml;"; break;
case '\u00D6' : enc = "&Ouml;"; break;
case '\u00FC' : enc = "&uuml;"; break;
case '\u00DC' : enc = "&Uuml;"; break;
case '\u00DF' : enc = "&szlig;"; break;
//misc
//case 0x80: enc = "&euro;"; break; sometimes euro symbol is ascii 128, should we suport it?
case '\u20AC': enc = "&euro;"; break;
case '\u00AB': enc = "&laquo;"; break;
case '\u00BB': enc = "&raquo;"; break;
case '\u00A0': enc = "&nbsp;"; break;
default:
if (((int)c) >= 0x80)
{
//encode all non basic latin characters
enc = "&#" + ((int)c) + ";";
}
break;
}
if (enc != null)
{
if (sb == null)
{
String soFar = string.substring(0, i);
sb = new StringBuilder(i + 8);
sb.append(soFar);
}
sb.append(enc);
}
else
{
if (sb != null)
{
sb.append(c);
}
}
}
if (sb == null)
{
return string;
}
else
{
return sb.toString();
}
}
/**
* Crop a label within a SPAN element, using ellipses '...' at the end of label and
* and encode the result for HTML output. A SPAN will only be generated if the label
* is beyond the default setting of 32 characters in length.
*
* @param text to crop and encode
*
* @return encoded and cropped resulting label HTML
*/
public static String cropEncode(String text)
{
return cropEncode(text, 32);
}
/**
* Crop a label within a SPAN element, using ellipses '...' at the end of label and
* and encode the result for HTML output. A SPAN will only be generated if the label
* is beyond the specified number of characters in length.
*
* @param text to crop and encode
* @param length length of string to crop too
*
* @return encoded and cropped resulting label HTML
*/
public static String cropEncode(String text, int length)
{
if (text.length() > length)
{
String label = text.substring(0, length - 3) + "...";
StringBuilder buf = new StringBuilder(length + 32 + text.length());
buf.append("<span title=\"")
.append(Utils.encode(text))
.append("\">")
.append(Utils.encode(label))
.append("</span>");
return buf.toString();
}
else
{
return Utils.encode(text);
}
}
/**
* Replace one string instance with another within the specified string
*
* @param str
* @param repl
* @param with
*
* @return replaced string
*/
public static String replace(String str, String repl, String with)
{
int lastindex = 0;
int pos = str.indexOf(repl);
// If no replacement needed, return the original string
// and save StringBuffer allocation/char copying
if (pos < 0)
{
return str;
}
int len = repl.length();
int lendiff = with.length() - repl.length();
StringBuilder out = new StringBuilder((lendiff <= 0) ? str.length() : (str.length() + (lendiff << 3)));
for (; pos >= 0; pos = str.indexOf(repl, lastindex = pos + len))
{
out.append(str.substring(lastindex, pos)).append(with);
}
return out.append(str.substring(lastindex, str.length())).toString();
}
/**
* Remove all occurances of a String from a String
*
* @param str String to remove occurances from
* @param match The string to remove
*
* @return new String with occurances of the match removed
*/
public static String remove(String str, String match)
{
int lastindex = 0;
int pos = str.indexOf(match);
// If no replacement needed, return the original string
// and save StringBuffer allocation/char copying
if (pos < 0)
{
return str;
}
int len = match.length();
StringBuilder out = new StringBuilder(str.length());
for (; pos >= 0; pos = str.indexOf(match, lastindex = pos + len))
{
out.append(str.substring(lastindex, pos));
}
return out.append(str.substring(lastindex, str.length())).toString();
}
/**
* 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
*/
public 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('"');
}
}
/**
* Get the hidden field name for any action component.
*
* All components that wish to simply encode a form value with their client ID can reuse the same
* hidden field within the parent form. NOTE: components which use this method must only encode
* their client ID as the value and nothing else!
*
* Build a shared field name from the parent form name and the string "act".
*
* @return hidden field name shared by all action components within the Form.
*/
public static String getActionHiddenFieldName(FacesContext context, UIComponent component)
{
return Utils.getParentForm(context, component).getClientId(context) + NamingContainer.SEPARATOR_CHAR + "act";
}
/**
* Helper to recursively render a component and it's child components
*
* @param context FacesContext
* @param component UIComponent
*
* @throws IOException
*/
public static void encodeRecursive(FacesContext context, UIComponent component)
throws IOException
{
if (component.isRendered() == true)
{
component.encodeBegin(context);
// follow the spec for components that render their children
if (component.getRendersChildren() == true)
{
component.encodeChildren(context);
}
else
{
if (component.getChildCount() != 0)
{
for (Iterator i=component.getChildren().iterator(); i.hasNext(); /**/)
{
encodeRecursive(context, (UIComponent)i.next());
}
}
}
component.encodeEnd(context);
}
}
/**
* Generate the JavaScript to submit set the specified hidden Form field to the
* supplied value and submit the parent Form.
*
* NOTE: the supplied hidden field name is added to the Form Renderer map for output.
*
* @param context FacesContext
* @param component UIComponent to generate JavaScript for
* @param fieldId Hidden field id to set value for
* @param fieldValue Hidden field value to set hidden field too on submit
*
* @return JavaScript event code
*/
public static String generateFormSubmit(FacesContext context, UIComponent component, String fieldId, String fieldValue)
{
return generateFormSubmit(context, component, fieldId, fieldValue, null);
}
/**
* Generate the JavaScript to submit set the specified hidden Form field to the
* supplied value and submit the parent Form.
*
* NOTE: the supplied hidden field name is added to the Form Renderer map for output.
*
* @param context FacesContext
* @param component UIComponent to generate JavaScript for
* @param fieldId Hidden field id to set value for
* @param fieldValue Hidden field value to set hidden field too on submit
* @param params Optional map of param name/values to output
*
* @return JavaScript event code
*/
public static String generateFormSubmit(FacesContext context, UIComponent component, String fieldId, String fieldValue, Map<String, String> params)
{
UIForm form = Utils.getParentForm(context, component);
if (form == null)
{
throw new IllegalStateException("Must nest components inside UIForm to generate form submit!");
}
String formClientId = form.getClientId(context);
StringBuilder buf = new StringBuilder(200);
buf.append("document.forms[");
buf.append("'");
buf.append(formClientId);
buf.append("'");
buf.append("]['");
buf.append(fieldId);
buf.append("'].value='");
buf.append(fieldValue);
buf.append("';");
if (params != null)
{
for (String name : params.keySet())
{
buf.append("document.forms[");
buf.append("'");
buf.append(formClientId);
buf.append("'");
buf.append("]['");
buf.append(name);
buf.append("'].value='");
buf.append(params.get(name));
buf.append("';");
// weak, but this seems to be the way Sun RI do it...
//FormRenderer.addNeededHiddenField(context, name);
HtmlFormRendererBase.addHiddenCommandParameter(form, name);
}
}
buf.append("document.forms[");
buf.append("'");
buf.append(formClientId);
buf.append("'");
buf.append("].submit()");
buf.append(";return false;");
// weak, but this seems to be the way Sun RI do it...
//FormRenderer.addNeededHiddenField(context, fieldId);
HtmlFormRendererBase.addHiddenCommandParameter(form, fieldId);
return buf.toString();
}
/**
* Generate the JavaScript to submit the parent Form.
*
* @param context FacesContext
* @param component UIComponent to generate JavaScript for
*
* @return JavaScript event code
*/
public static String generateFormSubmit(FacesContext context, UIComponent component)
{
UIForm form = Utils.getParentForm(context, component);
if (form == null)
{
throw new IllegalStateException("Must nest components inside UIForm to generate form submit!");
}
String formClientId = form.getClientId(context);
StringBuilder buf = new StringBuilder(48);
buf.append("document.forms[");
buf.append("'");
buf.append(formClientId);
buf.append("'");
buf.append("].submit()");
buf.append(";return false;");
return buf.toString();
}
/**
* Enum representing the client URL type to generate
*/
public enum URLMode {HTTP_DOWNLOAD, HTTP_INLINE, WEBDAV, CIFS, SHOW_DETAILS, FTP}
/**
* Generates a URL for the given usage for the given node.
*
* The supported values for the usage parameter are of URLMode enum type
* @see URLMode
*
* @param context Faces context
* @param node The node to generate the URL for
* @param usage What the URL is going to be used for
* @return The URL for the requested usage without the context path
*/
public static String generateURL(FacesContext context, Node node, URLMode usage)
{
String url = null;
switch (usage)
{
case WEBDAV:
{
// calculate a WebDAV URL for the given node
FileFolderService fileFolderService = Repository.getServiceRegistry(
context).getFileFolderService();
try
{
List<FileInfo> paths = fileFolderService.getNamePath(null, node.getNodeRef());
User user = Application.getCurrentUser(context);
// build up the webdav url
StringBuilder path = new StringBuilder("/").append(WebDAVServlet.WEBDAV_PREFIX);
// build up the path skipping the first path as it is the root folder
boolean homeSpaceFound = false;
for (int x = 1; x < paths.size(); x++)
{
path.append("/").append(paths.get(x).getName());
}
url = path.toString();
}
catch (Exception e)
{
if (logger.isWarnEnabled())
logger.warn("Failed to calculate webdav url", e);
}
break;
}
case CIFS:
{
// calculate a CIFS path for the given node
// get hold of the node service, cifsServer and navigation bean
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
NavigationBean navBean = (NavigationBean)context.getExternalContext().
getSessionMap().get("NavigationBean");
CIFSServer cifsServer = (CIFSServer)FacesContextUtils.getRequiredWebApplicationContext(
context).getBean("cifsServer");
if (nodeService != null && navBean != null && cifsServer != null)
{
DiskSharedDevice diskShare = cifsServer.getConfiguration().getPrimaryFilesystem();
if (diskShare != null)
{
ContentContext contentCtx = (ContentContext) diskShare.getContext();
NodeRef rootNode = contentCtx.getRootNode();
Path path = nodeService.getPath(node.getNodeRef());
url = Repository.getNamePath(nodeService, path, rootNode, "\\",
"file:///" + navBean.getCIFSServerPath(diskShare));
}
}
break;
}
case HTTP_DOWNLOAD:
{
url = DownloadContentServlet.generateDownloadURL(node.getNodeRef(), node.getName());
break;
}
case HTTP_INLINE:
{
url = DownloadContentServlet.generateBrowserURL(node.getNodeRef(), node.getName());
break;
}
case SHOW_DETAILS:
{
DictionaryService dd = Repository.getServiceRegistry(context).getDictionaryService();
// default to showing details of content
String outcome = "showDocDetails";
// if the node is a type of folder then make the outcome to show space details
if (dd.isSubClass(node.getType(), ContentModel.TYPE_FOLDER))
{
outcome = "showSpaceDetails";
}
// build the url
url = ExternalAccessServlet.generateExternalURL(outcome,
Repository.getStoreRef().getProtocol() + "/" +
Repository.getStoreRef().getIdentifier() + "/" + node.getId());
break;
}
case FTP:
{
// not implemented yet!
break;
}
}
return url;
}
/**
* Build a context path safe image tag for the supplied image path.
* Image path should be supplied with a leading slash '/'.
*
* @param context FacesContext
* @param image The local image path from the web folder with leading slash '/'
* @param width Width in pixels
* @param height Height in pixels
* @param alt Optional alt/title text
* @param onclick JavaScript onclick event handler code
*
* @return Populated <code>img</code> tag
*/
public static String buildImageTag(FacesContext context, String image, int width, int height, String alt, String onclick)
{
return buildImageTag(context, image, width, height, alt, onclick, null);
}
/**
* Build a context path safe image tag for the supplied image path.
* Image path should be supplied with a leading slash '/'.
*
* @param context FacesContext
* @param image The local image path from the web folder with leading slash '/'
* @param width Width in pixels
* @param height Height in pixels
* @param alt Optional alt/title text
* @param onclick JavaScript onclick event handler code
* @param align Optional HTML alignment value
*
* @return Populated <code>img</code> tag
*/
public static String buildImageTag(FacesContext context, String image, int width, int height, String alt, String onclick, String align)
{
StringBuilder buf = new StringBuilder(200);
buf.append("<img src=\"")
.append(context.getExternalContext().getRequestContextPath())
.append(image)
.append("\" width=")
.append(width)
.append(" height=")
.append(height)
.append(" border=0");
if (alt != null)
{
alt = Utils.encode(alt);
buf.append(" alt=\"")
.append(alt)
.append("\" title=\"")
.append(alt)
.append('"');
}
if (align != null)
{
buf.append(" align=")
.append(align);
}
if (onclick != null)
{
buf.append(" onclick=\"")
.append(onclick)
.append("\" style='cursor:pointer'");
}
buf.append('>');
return buf.toString();
}
/**
* Build a context path safe image tag for the supplied image path.
* Image path should be supplied with a leading slash '/'.
*
* @param context FacesContext
* @param image The local image path from the web folder with leading slash '/'
* @param width Width in pixels
* @param height Height in pixels
* @param alt Optional alt/title text
*
* @return Populated <code>img</code> tag
*/
public static String buildImageTag(FacesContext context, String image, int width, int height, String alt)
{
return buildImageTag(context, image, width, height, alt, null);
}
/**
* Build a context path safe image tag for the supplied image path.
* Image path should be supplied with a leading slash '/'.
*
* @param context FacesContext
* @param image The local image path from the web folder with leading slash '/'
* @param alt Optional alt/title text
*
* @return Populated <code>img</code> tag
*/
public static String buildImageTag(FacesContext context, String image, String alt)
{
return buildImageTag(context, image, alt, null);
}
/**
* Build a context path safe image tag for the supplied image path.
* Image path should be supplied with a leading slash '/'.
*
* @param context FacesContext
* @param image The local image path from the web folder with leading slash '/'
* @param alt Optional alt/title text
* @param align Optional HTML alignment value
*
* @return Populated <code>img</code> tag
*/
public static String buildImageTag(FacesContext context, String image, String alt, String align)
{
StringBuilder buf = new StringBuilder(128);
buf.append("<img src=\"")
.append(context.getExternalContext().getRequestContextPath())
.append(image)
.append("\" border=0");
if (alt != null)
{
alt = Utils.encode(alt);
buf.append(" alt=\"")
.append(alt)
.append("\" title=\"")
.append(alt)
.append('"');
}
if (align != null)
{
buf.append(" align=")
.append(align);
}
buf.append('>');
return buf.toString();
}
/**
* Return the parent UIForm component for the specified UIComponent
*
* @param context FaceContext
* @param component The UIComponent to find parent Form for
*
* @return UIForm parent or null if none found in hiearachy
*/
public static UIForm getParentForm(FacesContext context, UIComponent component)
{
UIComponent parent = component.getParent();
while (parent != null)
{
if (parent instanceof UIForm)
{
break;
}
parent = parent.getParent();
}
return (UIForm)parent;
}
/**
* Return the parent UIComponent implementing the NamingContainer interface for
* the specified UIComponent.
*
* @param context FaceContext
* @param component The UIComponent to find parent Form for
*
* @return NamingContainer parent or null if none found in hiearachy
*/
public static UIComponent getParentNamingContainer(FacesContext context, UIComponent component)
{
UIComponent parent = component.getParent();
while (parent != null)
{
if (parent instanceof NamingContainer)
{
break;
}
parent = parent.getParent();
}
return (UIComponent)parent;
}
/**
* Return the parent UIComponent implementing the IDataContainer interface for
* the specified UIComponent.
*
* @param context FaceContext
* @param component The UIComponent to find parent IDataContainer for
*
* @return IDataContainer parent or null if none found in hiearachy
*/
public static IDataContainer getParentDataContainer(FacesContext context, UIComponent component)
{
UIComponent parent = component.getParent();
while (parent != null)
{
if (parent instanceof IDataContainer)
{
break;
}
parent = parent.getParent();
}
return (IDataContainer)parent;
}
/**
* Determines whether the given component is disabled or readonly
*
* @param component The component to test
* @return true if the component is either disabled or set to readonly
*/
public static boolean isComponentDisabledOrReadOnly(UIComponent component)
{
boolean disabled = false;
boolean readOnly = false;
Object disabledAttr = component.getAttributes().get("disabled");
if (disabledAttr != null)
{
disabled = disabledAttr.equals(Boolean.TRUE);
}
if (disabled == false)
{
Object readOnlyAttr = component.getAttributes().get("disabled");
if (readOnlyAttr != null)
{
readOnly = readOnlyAttr.equals(Boolean.TRUE);
}
}
return disabled || readOnly;
}
/**
* Invoke the method encapsulated by the supplied MethodBinding
*
* @param context FacesContext
* @param method MethodBinding to invoke
* @param event ActionEvent to pass to the method of signature:
* public void myMethodName(ActionEvent event)
*/
public static void processActionMethod(FacesContext context, MethodBinding method, ActionEvent event)
{
try
{
method.invoke(context, new Object[] {event});
}
catch (EvaluationException e)
{
Throwable cause = e.getCause();
if (cause instanceof AbortProcessingException)
{
throw (AbortProcessingException)cause;
}
else
{
throw e;
}
}
}
/**
* Adds a global error message
*
* @param msg The error message
*/
public static void addErrorMessage(String msg)
{
addErrorMessage(msg, null);
}
/**
* Adds a global error message and logs exception details
*
* @param msg The error message
* @param err The exception to log
*/
public static void addErrorMessage(String msg, Throwable err)
{
FacesContext context = FacesContext.getCurrentInstance( );
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
context.addMessage(null, facesMsg);
if (err != null)
{
if ((err instanceof InvalidNodeRefException == false &&
err instanceof AccessDeniedException == false) || logger.isDebugEnabled())
{
logger.error(msg, err);
}
}
}
/**
* Adds a global status message that will be displayed by a Status Message UI component
*
* @param severity Severity of the message
* @param msg Text of the message
*/
public static void addStatusMessage(FacesMessage.Severity severity, String msg)
{
FacesContext fc = FacesContext.getCurrentInstance();
String time = getTimeFormat(fc).format(new Date(System.currentTimeMillis()));
FacesMessage fm = new FacesMessage(severity, time, msg);
fc.addMessage(UIStatusMessage.STATUS_MESSAGE, fm);
}
/**
* @return the formatter for locale sensitive Time formatting
*/
public static DateFormat getTimeFormat(FacesContext fc)
{
return getDateFormatFromPattern(fc, Application.getMessage(fc, MSG_TIME_PATTERN));
}
/**
* @return the formatter for locale sensitive Date formatting
*/
public static DateFormat getDateFormat(FacesContext fc)
{
return getDateFormatFromPattern(fc, Application.getMessage(fc, MSG_DATE_PATTERN));
}
/**
* @return the formatter for locale sensitive Date & Time formatting
*/
public static DateFormat getDateTimeFormat(FacesContext fc)
{
return getDateFormatFromPattern(fc, Application.getMessage(fc, MSG_DATE_TIME_PATTERN));
}
/**
* @return DataFormat object for the specified pattern
*/
private static DateFormat getDateFormatFromPattern(FacesContext fc, String pattern)
{
if (pattern == null)
{
throw new IllegalArgumentException("DateTime pattern is mandatory.");
}
try
{
return new SimpleDateFormat(pattern, Application.getLanguage(fc));
}
catch (IllegalArgumentException err)
{
throw new AlfrescoRuntimeException("Invalid DateTime pattern", err);
}
}
/**
* Return the image path to the filetype icon for the specified file name string
*
* @param name File name to build filetype icon path for
* @param small True for the small 16x16 icon or false for the large 32x32
*
* @return the image path for the specified node type or the default icon if not found
*/
public static String getFileTypeImage(String name, boolean small)
{
String image = (small ? DEFAULT_FILE_IMAGE16 : DEFAULT_FILE_IMAGE32);
int extIndex = name.lastIndexOf('.');
if (extIndex != -1 && name.length() > extIndex + 1)
{
String ext = name.substring(extIndex + 1).toLowerCase();
String key = ext + ' ' + (small ? "16" : "32");
// found file extension for appropriate size image
synchronized (s_fileExtensionMap)
{
image = s_fileExtensionMap.get(key);
if (image == null)
{
// not found create for first time
image = (small ? IMAGE_PREFIX16 : IMAGE_PREFIX32) + ext + IMAGE_POSTFIX;
// does this image exist on the web-server?
if (FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream(image) != null)
{
// found the image for this extension - save it for later
s_fileExtensionMap.put(key, image);
}
else
{
// not found, save the default image for this extension instead
image = (small ? DEFAULT_FILE_IMAGE16 : DEFAULT_FILE_IMAGE32);
s_fileExtensionMap.put(key, image);
}
}
}
}
return image;
}
}

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;
/**
* Class containing well known web resource paths for images etc.
*
* @author Kevin Roast
*/
public class WebResources
{
// Image paths
public static final String IMAGE_PREVIOUSPAGE_NONE = "/images/icons/PreviousPage_unavailable.gif";
public static final String IMAGE_PREVIOUSPAGE = "/images/icons/PreviousPage.gif";
public static final String IMAGE_FIRSTPAGE_NONE = "/images/icons/FirstPage_unavailable.gif";
public static final String IMAGE_FIRSTPAGE = "/images/icons/FirstPage.gif";
public static final String IMAGE_NEXTPAGE_NONE = "/images/icons/NextPage_unavailable.gif";
public static final String IMAGE_NEXTPAGE = "/images/icons/NextPage.gif";
public static final String IMAGE_LASTPAGE_NONE = "/images/icons/LastPage_unavailable.gif";
public static final String IMAGE_LASTPAGE = "/images/icons/LastPage.gif";
public static final String IMAGE_SORTUP = "/images/icons/sort_up.gif";
public static final String IMAGE_SORTDOWN = "/images/icons/sort_down.gif";
public static final String IMAGE_SORTNONE = "/images/icons/sort_flat.gif";
public static final String IMAGE_EXPANDED = "/images/icons/expanded.gif";
public static final String IMAGE_COLLAPSED = "/images/icons/collapsed.gif";
public static final String IMAGE_MOVELEFT = "/images/icons/move_left.gif";
public static final String IMAGE_MOVERIGHT = "/images/icons/move_right.gif";
public static final String IMAGE_GO_UP = "/images/icons/up.gif";
public static final String IMAGE_INFO = "/images/icons/info_icon.gif";
}

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;
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.converter;
import java.util.ResourceBundle;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import org.alfresco.web.app.Application;
/**
* Converter class to convert a Boolean value (including null) into a human readable form.
*
* @author Kevin Roast
*/
public class BooleanLabelConverter implements Converter
{
/**
* <p>The standard converter id for this converter.</p>
*/
public static final String CONVERTER_ID = "org.alfresco.faces.BooleanLabelConverter";
private static final String MSG_YES = "yes";
private static final String MSG_NO = "no";
/**
* @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String)
*/
public Object getAsObject(FacesContext context, UIComponent component, String value)
throws ConverterException
{
return Boolean.valueOf(value);
}
/**
* @see javax.faces.convert.Converter#getAsString(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
*/
public String getAsString(FacesContext context, UIComponent component, Object value)
throws ConverterException
{
ResourceBundle bundle = Application.getBundle(context);
String result = bundle.getString(MSG_NO);
if (value instanceof Boolean)
{
result = ((Boolean)value).booleanValue() ? bundle.getString(MSG_YES) : bundle.getString(MSG_NO);
}
return result;
}
}

View File

@@ -0,0 +1,109 @@
/*
* 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.converter;
import java.text.DecimalFormat;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import org.alfresco.web.app.Application;
/**
* Converter class to convert the size of an item in bytes into a readable KB/MB form.
*
* @author Kevin Roast
*/
public class ByteSizeConverter implements Converter
{
/**
* <p>The standard converter id for this converter.</p>
*/
public static final String CONVERTER_ID = "org.alfresco.faces.ByteSizeConverter";
private static final String MSG_POSTFIX_KB = "kilobyte";
private static final String MSG_POSTFIX_MB = "megabyte";
private static final String MSG_POSTFIX_GB = "gigabyte";
private static final String NUMBER_PATTERN = "###,###.##";
/**
* @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String)
*/
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
return Long.parseLong(value);
}
/**
* @see javax.faces.convert.Converter#getAsString(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
*/
public String getAsString(FacesContext context, UIComponent component, Object value)
{
long size;
if (value instanceof Long)
{
size = (Long)value;
}
else if (value instanceof String)
{
try
{
size = Long.parseLong((String)value);
}
catch (NumberFormatException ne)
{
return (String)value;
}
}
else
{
return "";
}
// get formatter
// TODO: can we cache this instance...? DecimalFormat is not threadsafe! Need threadlocal instance.
DecimalFormat formatter = new DecimalFormat(NUMBER_PATTERN);
StringBuilder buf = new StringBuilder();
if (size < 999999)
{
double val = ((double)size) / 1024.0;
buf.append(formatter.format(val))
.append(' ')
.append(Application.getMessage(context, MSG_POSTFIX_KB));
}
else if (size < 999999999)
{
double val = ((double)size) / 1048576.0;
buf.append(formatter.format(val))
.append(' ')
.append(Application.getMessage(context, MSG_POSTFIX_MB));
}
else
{
double val = ((double)size) / 1073741824.0;
buf.append(formatter.format(val))
.append(' ')
.append(Application.getMessage(context, MSG_POSTFIX_GB));
}
return buf.toString();
}
}

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.converter;
import java.util.Date;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.DateTimeConverter;
import org.alfresco.util.ISO8601DateFormat;
/**
* Converter class to convert an XML date representation into a Date
*
* @author gavinc
*/
public class XMLDateConverter extends DateTimeConverter
{
/**
* <p>The standard converter id for this converter.</p>
*/
public static final String CONVERTER_ID = "org.alfresco.faces.XMLDataConverter";
/**
* @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String)
*/
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
return ISO8601DateFormat.parse(value);
}
/**
* @see javax.faces.convert.Converter#getAsString(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
*/
public String getAsString(FacesContext context, UIComponent component, Object value)
{
String str = null;
if (value instanceof String)
{
Date date = ISO8601DateFormat.parse((String)value);
str = super.getAsString(context, component, date);
}
else
{
str = super.getAsString(context, component, value);
}
return str;
}
}

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.renderer;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.alfresco.web.ui.common.component.UIMenu;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author kevinr
*/
public class ActionLinkRenderer extends BaseRenderer
{
private static Log logger = LogFactory.getLog(ActionLinkRenderer.class);
// ------------------------------------------------------------------------------
// Renderer implementation
/**
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void decode(FacesContext context, UIComponent component)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = Utils.getActionHiddenFieldName(context, component);
String value = (String)requestMap.get(fieldId);
// we are clicked if the hidden field contained our client id
if (value != null && value.equals(component.getClientId(context)))
{
// get all the params for this actionlink, see if any values have been set
// on the request which match our params and set them into the component
UIActionLink link = (UIActionLink)component;
Map<String, String> destParams = link.getParameterMap();
destParams.clear();
Map<String, String> actionParams = getParameterMap(link);
if (actionParams != null)
{
for (String name : actionParams.keySet())
{
String paramValue = (String)requestMap.get(name);
destParams.put(name, paramValue);
}
}
ActionEvent event = new ActionEvent(component);
component.queueEvent(event);
}
}
/**
* @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeEnd(FacesContext context, UIComponent component) throws IOException
{
// always check for this flag - as per the spec
if (component.isRendered() == true)
{
Writer out = context.getResponseWriter();
UIActionLink link = (UIActionLink)component;
if (isInMenu(link) == true)
{
// render as menu item
out.write( renderMenuAction(context, link) );
}
else
{
// render as action link
out.write( renderActionLink(context, link) );
}
}
}
/**
* Render ActionLink as plain link and image
*
* @param context
* @param link
*
* @return action link HTML
*/
private String renderActionLink(FacesContext context, UIActionLink link)
{
Map attrs = link.getAttributes();
StringBuilder linkBuf = new StringBuilder(256);
if (link.getHref() == null)
{
linkBuf.append("<a href='#' onclick=\"");
// if we have an overriden onclick add that
if (link.getOnclick() != null)
{
linkBuf.append(link.getOnclick());
}
else
{
// generate JavaScript to set a hidden form field and submit
// a form which request attributes that we can decode
linkBuf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterMap(link)));
}
linkBuf.append('"');
}
else
{
String href = link.getHref();
if (href.startsWith("http") == false && href.startsWith("file") == false)
{
href = context.getExternalContext().getRequestContextPath() + href;
}
linkBuf.append("<a href=\"")
.append(href)
.append('"');
// output href 'target' attribute if supplied
if (link.getTarget() != null)
{
linkBuf.append(" target=\"")
.append(link.getTarget())
.append("\"");
}
}
if (attrs.get("style") != null)
{
linkBuf.append(" style=\"")
.append(attrs.get("style"))
.append('"');
}
if (attrs.get("styleClass") != null)
{
linkBuf.append(" class=")
.append(attrs.get("styleClass"));
}
if (attrs.get("tooltip") != null)
{
linkBuf.append(" title=\"")
.append(Utils.encode((String)attrs.get("tooltip")))
.append('"');
}
linkBuf.append('>');
StringBuilder buf = new StringBuilder(350);
if (link.getImage() != null)
{
int padding = link.getPadding();
if (padding != 0)
{
// TODO: make this width value a property!
buf.append("<table cellspacing=0 cellpadding=0><tr><td width=16>");
}
if (link.getShowLink() == false)
{
buf.append(linkBuf.toString());
}
// TODO: allow configuring of alignment attribute
buf.append(Utils.buildImageTag(context, link.getImage(), (String)link.getValue(), "absmiddle"));
if (link.getShowLink() == false)
{
buf.append("</a>");
}
else
{
if (padding != 0)
{
buf.append("</td><td style=\"padding:")
.append(padding)
.append("px\">");
}
else
{
// TODO: add horizontal spacing as component property
buf.append("<span style='padding-left:2px");
// text next to an image may need alignment
if (attrs.get("verticalAlign") != null)
{
buf.append(";vertical-align:")
.append(attrs.get("verticalAlign"));
}
buf.append("'>");
}
buf.append(linkBuf.toString());
buf.append(Utils.encode(link.getValue().toString()));
buf.append("</a>");
if (padding == 0)
{
buf.append("</span>");
}
}
if (padding != 0)
{
buf.append("</td></tr></table>");
}
}
else
{
buf.append(linkBuf.toString());
buf.append(Utils.encode(link.getValue().toString()));
buf.append("</a>");
}
return buf.toString();
}
/**
* Render ActionLink as menu image and item link
*
* @param context
* @param link
*
* @return action link HTML
*/
private String renderMenuAction(FacesContext context, UIActionLink link)
{
StringBuilder buf = new StringBuilder(256);
buf.append("<tr><td>");
// render image cell first for a menu
if (link.getImage() != null)
{
buf.append(Utils.buildImageTag(context, link.getImage(), (String)link.getValue()));
}
buf.append("</td><td");
int padding = link.getPadding();
if (padding != 0)
{
buf.append(" style=\"padding:")
.append(padding)
.append("px\"");
}
buf.append(">");
Map attrs = link.getAttributes();
// render text link cell for the menu
if (attrs.get("href") == null)
{
buf.append("<a href='#' onclick=\"");
buf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterMap(link)));
buf.append('"');
}
else
{
String href = (String)attrs.get("href");
if (href.startsWith("http") == false)
{
href = context.getExternalContext().getRequestContextPath() + href;
}
buf.append("<a href=\"")
.append(href)
.append('"');
// output href 'target' attribute if supplied
if (link.getTarget() != null)
{
buf.append(" target=\"")
.append(link.getTarget())
.append("\"");
}
}
if (attrs.get("style") != null)
{
buf.append(" style=\"")
.append(attrs.get("style"))
.append('"');
}
if (attrs.get("styleClass") != null)
{
buf.append(" class=")
.append(attrs.get("styleClass"));
}
buf.append('>');
buf.append(Utils.encode(link.getValue().toString()));
buf.append("</a>");
buf.append("</td></tr>");
return buf.toString();
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* Return true if the action link is present within a UIMenu component container
*
* @param link The ActionLink to test
*
* @return true if the action link is present within a UIMenu component
*/
private static boolean isInMenu(UIActionLink link)
{
UIComponent parent = link.getParent();
while (parent != null)
{
if (parent instanceof UIMenu)
{
break;
}
parent = parent.getParent();
}
return (parent != null);
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.renderer;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
/**
* Base renderer class. Contains helper methods to assist most renderers.
*
* @author kevinr
*/
public abstract class BaseRenderer extends Renderer
{
/**
* 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('"');
}
}
/**
* Ensures that the given context and component are not null. This method
* should be called by all renderer methods that are given these parameters.
*
* @param ctx Faces context
* @param component The component
*/
protected static void assertParmeters(FacesContext ctx, UIComponent component)
{
if (ctx == null)
{
throw new IllegalStateException("context can not be null");
}
if (component == null)
{
throw new IllegalStateException("component can not be null");
}
}
/**
* Return the map of name/value pairs for any child UIParameter components.
*
* @param component to find UIParameter child values for
*
* @return a Map of name/value pairs or null if none found
*/
protected static Map<String, String> getParameterMap(UIComponent component)
{
Map<String, String> params = null;
if (component.getChildCount() != 0)
{
params = new HashMap<String, String>(3, 1.0f);
for (Iterator i=component.getChildren().iterator(); i.hasNext(); /**/)
{
UIComponent child = (UIComponent)i.next();
if (child instanceof UIParameter)
{
UIParameter param = (UIParameter)child;
params.put(param.getName(), (String)param.getValue());
}
}
}
return params;
}
}

View File

@@ -0,0 +1,161 @@
/*
* 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.renderer;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
import org.alfresco.web.ui.common.component.UIBreadcrumb;
/**
* Renderer class for the UIBreadcrumb component
*
* @author Kevin Roast
*/
public class BreadcrumbRenderer extends BaseRenderer
{
// ------------------------------------------------------------------------------
// Renderer implementation
/**
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void decode(FacesContext context, UIComponent component)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = getHiddenFieldName(context, component);
String value = (String)requestMap.get(fieldId);
if (value != null && value.length() != 0)
{
// create a breadcrumb specific action event if we were clicked
int selectedIndex = Integer.parseInt(value);
UIBreadcrumb.BreadcrumbEvent event = new UIBreadcrumb.BreadcrumbEvent(component, selectedIndex);
component.queueEvent(event);
}
}
/**
* @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeBegin(FacesContext context, UIComponent component) throws IOException
{
// always check for this flag - as per the spec
if (component.isRendered() == true)
{
Writer out = context.getResponseWriter();
UIBreadcrumb breadcrumb = (UIBreadcrumb)component;
// get the List of IBreadcrumbHandler elements from the component
List<IBreadcrumbHandler> elements = (List)breadcrumb.getValue();
boolean first = true;
for (int index=0; index<elements.size(); index++)
{
IBreadcrumbHandler element = elements.get(index);
// handle not optionally hiding the root part
if (index != 0 || breadcrumb.getShowRoot() == true)
{
out.write( renderBreadcrumb(context, breadcrumb, element.toString(), index, first) );
first = false;
}
}
}
}
// ------------------------------------------------------------------------------
// Private helpers
/**
* Render a single breadcrumb element as a link on the page
*
* @param context FacesContext
* @param bc The current UIBreadcrumb component
* @param element Text for the breadcrumb element
* @param index The index of the element into the original breadcrumb path
* @param first True is this is the root element
*
* @return HTML for this breadcrumb element
*/
private String renderBreadcrumb(FacesContext context, UIBreadcrumb bc, String element, int index, boolean first)
{
// render breadcrumb link element
StringBuilder buf = new StringBuilder(200);
// output separator
if (first == false)
{
buf.append(' ')
.append(bc.getSeparator())
.append(' ');
}
// generate JavaScript to set a hidden form field and submit
// a form which request attributes that we can decode
buf.append("<a href='#' onclick=\"");
buf.append(Utils.generateFormSubmit(context, bc, getHiddenFieldName(context, bc), Integer.toString(index)));
buf.append('"');
if (bc.getAttributes().get("style") != null)
{
buf.append(" style=\"")
.append(bc.getAttributes().get("style"))
.append('"');
}
if (bc.getAttributes().get("styleClass") != null)
{
buf.append(" class=")
.append(bc.getAttributes().get("styleClass"));
}
if (bc.getAttributes().get("tooltip") != null)
{
buf.append(" title=\"")
.append(bc.getAttributes().get("tooltip"))
.append('"');
}
buf.append('>');
// output path element text
// TODO: optionally crop text length with ellipses - use title attribute for all
buf.append(Utils.encode(element));
// close tag
buf.append("</a>");
return buf.toString();
}
/**
* Get the hidden field name for this breadcrumb.
* Assume there will not be many breadcrumbs on a page - therefore a hidden field
* for each is not a significant issue.
*
* @return hidden field name
*/
private static String getHiddenFieldName(FacesContext context, UIComponent component)
{
return component.getClientId(context);
}
}

View File

@@ -0,0 +1,318 @@
/*
* 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.renderer;
import java.io.IOException;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.ConverterException;
import javax.faces.model.SelectItem;
import org.alfresco.web.app.Application;
/**
* @author kevinr
*
* Example of a custom JSF renderer. This demonstrates how to encode/decode a set
* of input field params that we use to generate a Date object. This object is held
* in our component and the renderer will output it to the page.
*/
public class DatePickerRenderer extends BaseRenderer
{
private static final String FIELD_YEAR = "_year";
private static final String FIELD_MONTH = "_month";
private static final String FIELD_DAY = "_day";
private static final String FIELD_HOUR = "_hour";
private static final String FIELD_MINUTE = "_minute";
/**
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*
* The decode method takes the parameters from the external requests, finds the
* ones revelant to this component and decodes the results into an object known
* as the "submitted value".
*/
public void decode(FacesContext context, UIComponent component)
{
try
{
// TODO: should check for disabled/readonly here - no need to decode
String clientId = component.getClientId(context);
Map params = context.getExternalContext().getRequestParameterMap();
String year = (String)params.get(clientId + FIELD_YEAR);
if (year != null)
{
// found data for our component
String month = (String)params.get(clientId + FIELD_MONTH);
String day = (String)params.get(clientId + FIELD_DAY);
String hour = (String)params.get(clientId + FIELD_HOUR);
String minute = (String)params.get(clientId + FIELD_MINUTE);
// we encode the values needed for the component as we see fit
int[] parts = new int[5];
parts[0] = Integer.parseInt(year);
parts[1] = Integer.parseInt(month);
parts[2] = Integer.parseInt(day);
parts[3] = Integer.parseInt(hour);
parts[4] = Integer.parseInt(minute);
// save the data in an object for our component as the "EditableValueHolder"
// all UI Input Components support this interface for the submitted value
((EditableValueHolder)component).setSubmittedValue(parts);
}
}
catch (NumberFormatException nfe)
{
// just ignore the error and skip the update of the property
}
}
/**
* @see javax.faces.render.Renderer#getConvertedValue(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
*
* In the Process Validations phase, this method is called to convert the values
* to the datatype as required by the component.
*
* It is possible at this point that a custom Converter instance will be used - this
* is why we have not yet converted the values to a data type.
*/
public Object getConvertedValue(FacesContext context, UIComponent component, Object val) throws ConverterException
{
int[] parts = (int[])val;
Calendar date = new GregorianCalendar(parts[0], parts[1], parts[2], parts[3], parts[4]);
return date.getTime();
}
/**
* @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*
* All rendering logic for this component is implemented here. A renderer for an
* input component must render the submitted value if it's set, and use the local
* value only if there is no submitted value.
*/
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException
{
// always check for this flag - as per the spec
if (component.isRendered() == true)
{
Date date = null;
// this is part of the spec:
// first you attempt to build the date from the submitted value
int[] submittedValue = (int[])((EditableValueHolder)component).getSubmittedValue();
if (submittedValue != null)
{
date = (Date)getConvertedValue(context, component, submittedValue);
}
else
{
// second if no submitted value is found, default to the current value
Object value = ((ValueHolder)component).getValue();
// finally check for null value and create default if needed
date = value instanceof Date ? (Date)value : new Date();
}
// get the attributes from the component we need for rendering
int nStartYear = 1990;
Integer startYear = (Integer)component.getAttributes().get("startYear");
if (startYear != null)
{
nStartYear = startYear.intValue();
}
int nYearCount = 10;
Integer yearCount = (Integer)component.getAttributes().get("yearCount");
if (yearCount != null)
{
nYearCount = yearCount.intValue();
}
// now we render the output for our component
// we create 3 drop-down menus for day, month and year and
// two text fields for the hour and minute
String clientId = component.getClientId(context);
ResponseWriter out = context.getResponseWriter();
// note that we build a client id for our form elements that we are then
// able to decode() as above.
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
renderMenu(out, component, getDays(), calendar.get(Calendar.DAY_OF_MONTH), clientId + FIELD_DAY);
renderMenu(out, component, getMonths(), calendar.get(Calendar.MONTH), clientId + FIELD_MONTH);
renderMenu(out, component, getYears(nStartYear, nYearCount), calendar.get(Calendar.YEAR), clientId + FIELD_YEAR);
// make sure we have a flag to determine whether to show the time
Boolean showTime = (Boolean)component.getAttributes().get("showTime");
if (showTime == null)
{
showTime = Boolean.FALSE;
}
out.write("&nbsp;");
renderTimeElement(out, component, calendar.get(Calendar.HOUR_OF_DAY), clientId + FIELD_HOUR, showTime.booleanValue());
if (showTime.booleanValue())
{
out.write("&nbsp;:&nbsp;");
}
renderTimeElement(out, component, calendar.get(Calendar.MINUTE), clientId + FIELD_MINUTE, showTime.booleanValue());
}
}
/**
* Render a drop-down menu to represent an element for the date picker.
*
* @param out Response Writer to output too
* @param component The compatible component
* @param items To display in the drop-down list
* @param selected Which item index is selected
* @param clientId Client Id to use
*
* @throws IOException
*/
private void renderMenu(ResponseWriter out, UIComponent component, List items,
int selected, String clientId)
throws IOException
{
out.write("<select");
outputAttribute(out, clientId, "name");
if (component.getAttributes().get("styleClass") != null)
{
outputAttribute(out, component.getAttributes().get("styleClass"), "class");
}
if (component.getAttributes().get("style") != null)
{
outputAttribute(out, component.getAttributes().get("style"), "style");
}
if (component.getAttributes().get("disabled") != null)
{
outputAttribute(out, component.getAttributes().get("disabled"), "disabled");
}
out.write(">");
for (Iterator i=items.iterator(); i.hasNext(); /**/)
{
SelectItem item = (SelectItem)i.next();
Integer value = (Integer)item.getValue();
out.write("<option");
outputAttribute(out, value, "value");
// show selected value
if (value.intValue() == selected)
{
outputAttribute(out, "selected", "selected");
}
out.write(">");
out.write(item.getLabel());
out.write("</option>");
}
out.write("</select>");
}
/**
* Renders either the hour or minute field
*
* @param out The ResponseWriter
* @param currentValue The value of the hour or minute
* @param clientId The id to use for the field
*/
private void renderTimeElement(ResponseWriter out, UIComponent component,
int currentValue, String clientId, boolean showTime) throws IOException
{
out.write("<input");
outputAttribute(out, clientId, "name");
if (showTime)
{
out.write(" type='text' size='1' maxlength='2'");
if (component.getAttributes().get("disabled") != null)
{
outputAttribute(out, component.getAttributes().get("disabled"), "disabled");
}
}
else
{
out.write(" type='hidden'");
}
// make sure there are always 2 digits
String strValue = Integer.toString(currentValue);
if (strValue.length() == 1)
{
strValue = "0" + strValue;
}
outputAttribute(out, strValue, "value");
out.write("/>");
}
private List getYears(int startYear, int yearCount)
{
List<SelectItem> years = new ArrayList<SelectItem>();
for (int i=startYear; i<startYear + yearCount; i++)
{
Integer year = Integer.valueOf(i);
years.add(new SelectItem(year, year.toString()));
}
return years;
}
private List getMonths()
{
// get names of the months for default locale
Locale locale = Application.getLanguage(FacesContext.getCurrentInstance());
if (locale == null)
{
locale = locale.getDefault();
}
DateFormatSymbols dfs = new DateFormatSymbols(locale);
String[] names = dfs.getMonths();
List<SelectItem> months = new ArrayList<SelectItem>(12);
for (int i=0; i<12; i++)
{
Integer key = Integer.valueOf(i);
months.add(new SelectItem(key, names[i]));
}
return months;
}
private List getDays()
{
List<SelectItem> days = new ArrayList<SelectItem>(31);
for (int i=1; i<32; i++)
{
Integer day = Integer.valueOf(i);
days.add(new SelectItem(day, day.toString()));
}
return days;
}
}

View File

@@ -0,0 +1,114 @@
/*
* 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.renderer;
import java.io.IOException;
import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.web.app.Application;
import org.alfresco.web.ui.common.PanelGenerator;
import org.alfresco.web.ui.common.Utils;
/**
* Renderer that displays any errors that occurred in the previous lifecylce
* processing within a gradient panel
*
* @author gavinc
*/
public class ErrorsRenderer extends BaseRenderer
{
private static final String DEFAULT_MESSAGE = "wizard_errors";
/**
* @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeBegin(FacesContext context, UIComponent component) throws IOException
{
if (component.isRendered() == false)
{
return;
}
Iterator messages = context.getMessages();
if (messages.hasNext())
{
ResponseWriter out = context.getResponseWriter();
String contextPath = context.getExternalContext().getRequestContextPath();
String styleClass = (String)component.getAttributes().get("styleClass");
String message = (String)component.getAttributes().get("message");
if (message == null)
{
// because we are using the standard messages component value binding
// would not be handled for the message attribute so do it here
ValueBinding vb = component.getValueBinding("message");
if (vb != null)
{
message = (String)vb.getValue(context);
}
if (message == null)
{
message = Application.getMessage(context, DEFAULT_MESSAGE);
}
}
PanelGenerator.generatePanelStart(out, contextPath, "yellowInner", "#ffffcc");
out.write("\n<div");
if (styleClass != null)
{
outputAttribute(out, styleClass, "class");
}
out.write(">");
out.write("<img src='");
out.write(contextPath);
out.write("/images/icons/info_icon.gif' alt='Error' align='absmiddle'/>&nbsp;&nbsp;");
out.write(Utils.encode(message));
out.write("\n<ul style='margin:2px;'>");
while (messages.hasNext())
{
FacesMessage fm = (FacesMessage)messages.next();
out.write("<li>");
out.write(Utils.encode(fm.getSummary()));
out.write("</li>\n");
}
out.write("</ul></div>\n");
PanelGenerator.generatePanelEnd(out, contextPath, "yellowInner");
// TODO: Expose this as a configurable attribute i.e. padding at bottom
out.write("<div style='padding:2px;'></div>");
}
}
/**
* @see javax.faces.render.Renderer#getRendersChildren()
*/
public boolean getRendersChildren()
{
return false;
}
}

View File

@@ -0,0 +1,281 @@
/*
* 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.renderer;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIImagePicker;
import org.alfresco.web.ui.common.component.UIListItem;
import org.alfresco.web.ui.common.component.UIListItems;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Renderer for the image picker component that outputs the list of images
* as radio buttons
*
* @author gavinc
*/
public class ImagePickerRadioRenderer extends BaseRenderer
{
private static Log logger = LogFactory.getLog(ImagePickerRadioRenderer.class);
private int columns;
private int position;
private boolean open;
// ------------------------------------------------------------------------------
// Renderer implemenation
/**
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void decode(FacesContext context, UIComponent component)
{
if (Utils.isComponentDisabledOrReadOnly(component))
{
return;
}
String clientId = component.getClientId(context);
Map paramsMap = context.getExternalContext().getRequestParameterMap();
String submittedValue = (String)paramsMap.get(clientId);
if (logger.isDebugEnabled())
logger.debug("Submitted value = " + submittedValue);
((UIInput)component).setSubmittedValue(submittedValue);
}
/**
* @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeBegin(FacesContext context, UIComponent component) throws IOException
{
if (component.isRendered() == false)
{
return;
}
// setup counters
this.columns = 1;
this.position = 0;
this.open = false;
ResponseWriter out = context.getResponseWriter();
UIImagePicker imagePicker = (UIImagePicker)component;
Map attrs = imagePicker.getAttributes();
out.write("<table cellpadding='0'");
outputAttribute(out, attrs.get("spacing"), "cellspacing");
outputAttribute(out, attrs.get("styleClass"), "class");
outputAttribute(out, attrs.get("style"), "style");
out.write(">\n");
}
/**
* @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeChildren(FacesContext context, UIComponent component) throws IOException
{
if (component.isRendered() == false)
{
return;
}
UIImagePicker imagePicker = (UIImagePicker)component;
Map attrs = imagePicker.getAttributes();
Integer cols = (Integer)attrs.get("columns");
if (cols != null && cols instanceof Integer)
{
this.columns = cols.intValue();
}
// retrieve the onclick handler, if there is one
String onclick = (String)attrs.get("onclick");
ResponseWriter out = context.getResponseWriter();
// get the child components
for (Iterator i = imagePicker.getChildren().iterator(); i.hasNext(); /**/)
{
UIComponent child = (UIComponent)i.next();
if (child instanceof UIListItems)
{
// get the value of the list items component and iterate
// through it's collection
Object listItems = ((UIListItems)child).getValue();
if (listItems instanceof Collection)
{
Iterator iter = ((Collection)listItems).iterator();
while (iter.hasNext())
{
UIListItem item = (UIListItem)iter.next();
renderItem(context, out, imagePicker, item, onclick);
}
}
}
else if (child instanceof UIListItem && child.isRendered() == true)
{
// found a valid UIListItem child to render
UIListItem item = (UIListItem)child;
renderItem(context, out, imagePicker, item, onclick);
}
}
// if we are in the middle of a row, close it
if (open)
{
out.write("</tr>\n");
}
}
/**
* @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeEnd(FacesContext context, UIComponent component) throws IOException
{
if (component.isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
out.write("</table>");
}
/**
* @see javax.faces.render.Renderer#getRendersChildren()
*/
public boolean getRendersChildren()
{
return true;
}
/**
* Renders the given item as a radio button selection choice
*
* @param context Faces context
* @param out ReponseWriter to write output to
* @param imagePicker The parent component
* @param item The item to render
* @param onclick The onClick JavaScript handler (may be null)
*/
private void renderItem(FacesContext context, ResponseWriter out,
UIImagePicker imagePicker, UIListItem item, String onclick)
throws IOException
{
String tooltip = (String)item.getAttributes().get("tooltip");
// if we are at the start of another row output "tr"
if ((this.position % this.columns) == 0)
{
// if we are at the end of a row, close it
if (this.open)
{
out.write("</tr>\n");
this.open = false;
}
out.write("<tr>");
// we have started the row
this.open = true;
}
// output the next "cell" i.e. a radio button, the image and optional label
out.write("<td>");
out.write("<input type='radio' name='");
out.write(imagePicker.getClientId(context));
out.write("' id='");
out.write(imagePicker.getClientId(context));
out.write("' value='");
// TODO: need to take into account values that may need to be converted,
// for now presume a string is OK
out.write(item.getValue().toString());
out.write("'");
// determine whether this item should be selected
Object currentValue = imagePicker.getSubmittedValue();
if (currentValue == null)
{
currentValue = imagePicker.getValue();
}
Object itemValue = item.getValue();
if (itemValue != null && itemValue.equals(currentValue))
{
out.write(" checked='true'");
}
if (tooltip != null)
{
out.write(" title='");
out.write(Utils.encode(tooltip));
out.write("'");
}
if (onclick != null)
{
out.write(" onclick='");
out.write(onclick);
out.write("'");
}
// if (item.isDisabled())
// {
// out.write(" disabled='true'");
// }
out.write(">");
out.write("</td><td align='center'>");
// get the image and make sure there is one!
String image = (String)item.getAttributes().get("image");
if (image == null)
{
throw new IllegalStateException("All child items must specify an image");
}
out.write(Utils.buildImageTag(context, image, tooltip));
String label = (String)item.getAttributes().get("label");
if (label != null && label.length() > 0)
{
out.write("<br/>");
out.write(Utils.encode(label));
}
out.write("</td>");
// we've finished the item so move the position on
this.position++;
}
}

View File

@@ -0,0 +1,293 @@
/*
* 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.renderer;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
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 org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIListItem;
import org.alfresco.web.ui.common.component.UIModeList;
/**
* @author kevinr
*/
public class ModeListRenderer extends BaseRenderer
{
// ------------------------------------------------------------------------------
// Renderer implemenation
/**
* @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void decode(FacesContext context, UIComponent component)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = getHiddenFieldName(context, component);
String value = (String)requestMap.get(fieldId);
// we encoded the value to start with our Id
if (value != null && value.startsWith(component.getClientId(context) + NamingContainer.SEPARATOR_CHAR))
{
// found a new selected value for this ModeList
// queue an event to represent the change
// TODO: NOTE: The value object is passed in as a String here - is this a problem?
// As the 'value' field for a ModeListItem can contain Object...
Object selectedValue = value.substring(component.getClientId(context).length() + 1);
UIModeList.ModeListItemSelectedEvent event = new UIModeList.ModeListItemSelectedEvent(component, selectedValue);
component.queueEvent(event);
}
}
/**
* @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeBegin(FacesContext context, UIComponent component) throws IOException
{
if (component.isRendered() == false)
{
return;
}
UIModeList list = (UIModeList)component;
ResponseWriter out = context.getResponseWriter();
// start outer table container the list items
Map attrs = list.getAttributes();
out.write("<table cellspacing=1 cellpadding=0");
outputAttribute(out, attrs.get("styleClass"), "class");
outputAttribute(out, attrs.get("style"), "style");
outputAttribute(out, attrs.get("width"), "width");
out.write('>');
// horizontal rendering outputs a single row with each item as a column cell
if (list.isHorizontal() == true)
{
out.write("<tr>");
}
// output title row if present
if (list.getLabel() != null)
{
// each row is an inner table with a single row and 2 columns
// first column contains an icon if present, second column contains text
if (list.isHorizontal() == false)
{
out.write("<tr>");
}
out.write("<td><table cellpadding=0 width=100%");
outputAttribute(out, attrs.get("itemSpacing"), "cellspacing");
out.write("><tr>");
// output icon column
if (list.getIconColumnWidth() != 0)
{
out.write("<td");
outputAttribute(out, list.getIconColumnWidth(), "width");
out.write("></td>");
}
// output title label
out.write("<td><span");
outputAttribute(out, attrs.get("labelStyle"), "style");
outputAttribute(out, attrs.get("labelStyleClass"), "class");
out.write('>');
out.write(Utils.encode(list.getLabel()));
out.write("</span></td></tr></table></td>");
if (list.isHorizontal() == false)
{
out.write("</tr>");
}
}
}
/**
* @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeChildren(FacesContext context, UIComponent component) throws IOException
{
if (component.isRendered() == false)
{
return;
}
UIModeList list = (UIModeList)component;
Map attrs = list.getAttributes();
ResponseWriter out = context.getResponseWriter();
String selectedImage = (String)attrs.get("selectedImage");
// get the child components
for (Iterator i=list.getChildren().iterator(); i.hasNext(); /**/)
{
UIComponent child = (UIComponent)i.next();
if (child instanceof UIListItem && child.isRendered() == true)
{
// found a valid UIListItem child to render
UIListItem item = (UIListItem)child;
// each row is an inner table with a single row and 2 columns
// first column contains an icon if present, second column contains text
if (list.isHorizontal() == false)
{
out.write("<tr>");
}
out.write("<td><table cellpadding=0 width=100%");
outputAttribute(out, attrs.get("itemSpacing"), "cellspacing");
// if selected value render different style for the item
boolean selected = item.getValue().equals(list.getValue());
if (selected == true)
{
outputAttribute(out, attrs.get("selectedStyleClass"), "class");
outputAttribute(out, attrs.get("selectedStyle"), "style");
}
else
{
outputAttribute(out, attrs.get("itemStyleClass"), "class");
outputAttribute(out, attrs.get("itemStyle"), "style");
}
out.write("><tr>");
// output icon column
if (list.getIconColumnWidth() != 0)
{
out.write("<td");
outputAttribute(out, list.getIconColumnWidth(), "width");
out.write(">");
// if the "selectedImage" property is set and this item is selected then show it
if (selected == true && selectedImage != null)
{
out.write( Utils.buildImageTag(context, selectedImage, item.getTooltip()) );
}
else
{
// else show the image set for the individual item
String image = (String)child.getAttributes().get("image");
if (image != null)
{
out.write( Utils.buildImageTag(context, image, item.getTooltip()) );
}
}
out.write("</td>");
}
// output item link
out.write("<td>");
if (!list.isDisabled() && !item.isDisabled())
{
out.write("<a href='#' onclick=\"");
// generate javascript to submit the value of the child component
String value = list.getClientId(context) + NamingContainer.SEPARATOR_CHAR + (String)child.getAttributes().get("value");
out.write(Utils.generateFormSubmit(context, list, getHiddenFieldName(context, list), value));
out.write('"');
}
else
{
out.write("<span");
outputAttribute(out, attrs.get("disabledStyleClass"), "class");
outputAttribute(out, attrs.get("disabledStyle"), "style");
}
// render style for the item link
if (item.getValue().equals(list.getValue()))
{
outputAttribute(out, attrs.get("selectedLinkStyleClass"), "class");
outputAttribute(out, attrs.get("selectedLinkStyle"), "style");
}
else
{
outputAttribute(out, attrs.get("itemLinkStyleClass"), "class");
outputAttribute(out, attrs.get("itemLinkStyle"), "style");
}
outputAttribute(out, child.getAttributes().get("tooltip"), "title");
out.write('>');
out.write(Utils.encode(item.getLabel()));
if (!list.isDisabled() && !item.isDisabled())
{
out.write("</a>");
}
else
{
out.write("</span>");
}
out.write("</td></tr></table></td>");
if (list.isHorizontal() == false)
{
out.write("</tr>");
}
}
}
}
/**
* @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeEnd(FacesContext context, UIComponent component) throws IOException
{
if (component.isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
// end outer table
if (((UIModeList)component).isHorizontal() == true)
{
out.write("</tr>");
}
out.write("</table>");
}
/**
* @see javax.faces.render.Renderer#getRendersChildren()
*/
public boolean getRendersChildren()
{
return true;
}
/**
* We use a hidden field name based on the parent form component Id and
* the string "modelist" to give a hidden field name that can be shared by all
* ModeList components within a single UIForm component.
*
* @return hidden field name
*/
private static String getHiddenFieldName(FacesContext context, UIComponent component)
{
UIForm form = Utils.getParentForm(context, component);
return form.getClientId(context) + NamingContainer.SEPARATOR_CHAR + "modelist";
}
}

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.renderer.data;
import java.io.IOException;
import javax.faces.context.FacesContext;
import org.alfresco.web.ui.common.component.data.UIColumn;
import org.alfresco.web.ui.common.component.data.UIRichList;
/**
* Contract for implementations capable of rendering the columns for a Rich List
* component.
*
* @author kevinr
*/
public interface IRichListRenderer
{
/**
* Callback executed by the RichList component to render any adornments before
* the main list rows are rendered. This is generally used to output header items.
*
* @param context FacesContext
* @param richList The parent RichList component
* @param columns Array of columns to be shown
*
* @throws IOException
*/
public void renderListBefore(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException;
/**
* Callback executed by the RichList component once per row of data to be rendered.
* The bean used as the current row data is provided, but generally rendering of the
* column data will be performed by recursively encoding Column child components.
*
* @param context FacesContext
* @param richList The parent RichList component
* @param columns Array of columns to be shown
* @param row The data bean for the current row
*
* @throws IOException
*/
public void renderListRow(FacesContext context, UIRichList richList, UIColumn[] columns, Object row)
throws IOException;
/**
* Callback executed by the RichList component to render any adornments after
* the main list rows are rendered. This is generally used to output footer items.
*
* @param context FacesContext
* @param richList The parent RichList component
* @param columns Array of columns to be shown
*
* @throws IOException
*/
public void renderListAfter(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException;
/**
* Return the unique view mode identifier that this renderer is responsible for.
*
* @return Unique view mode identifier for this renderer e.g. "icons" or "details"
*/
public String getViewModeID();
}

View File

@@ -0,0 +1,735 @@
/*
* 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.renderer.data;
import java.io.IOException;
import java.util.ArrayList;
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 org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.data.UIColumn;
import org.alfresco.web.ui.common.component.data.UIRichList;
import org.alfresco.web.ui.common.renderer.BaseRenderer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author kevinr
*/
public class RichListRenderer extends BaseRenderer
{
// ------------------------------------------------------------------------------
// Renderer implemenation
/**
* @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException
{
// always check for this flag - as per the spec
if (component.isRendered() == true)
{
ResponseWriter out = context.getResponseWriter();
Map attrs = component.getAttributes();
out.write("<table cellspacing=0 cellpadding=0");
outputAttribute(out, attrs.get("styleClass"), "class");
outputAttribute(out, attrs.get("style"), "style");
outputAttribute(out, attrs.get("width"), "width");
out.write(">");
}
}
/**
* @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeChildren(FacesContext context, UIComponent component)
throws IOException
{
if (component.isRendered() == true)
{
// the RichList component we are working with
UIRichList richList = (UIRichList)component;
// prepare the component current row against the current page settings
richList.bind();
// collect child column components so they can be passed to the renderer
List<UIColumn> columnList = new ArrayList<UIColumn>(8);
for (Iterator i=richList.getChildren().iterator(); i.hasNext(); /**/)
{
UIComponent child = (UIComponent)i.next();
if (child instanceof UIColumn)
{
columnList.add((UIColumn)child);
}
}
UIColumn[] columns = new UIColumn[columnList.size()];
columnList.toArray(columns);
// get the renderer instance
IRichListRenderer renderer = (IRichListRenderer)richList.getViewRenderer();
if (renderer == null)
{
throw new IllegalStateException("IRichListRenderer must be available in UIRichList!");
}
// call render-before to output headers if required
ResponseWriter out = context.getResponseWriter();
out.write("<thead>");
renderer.renderListBefore(context, richList, columns);
out.write("</thead>");
out.write("<tbody>");
if (richList.isDataAvailable() == true)
{
while (richList.isDataAvailable() == true)
{
// render each row in turn
renderer.renderListRow(context, richList, columns, richList.nextRow());
}
}
else
{
// if no items present, render the facet with the "no items found" message
UIComponent emptyComponent = richList.getEmptyMessage();
if (emptyComponent != null)
{
emptyComponent.encodeBegin(context);
emptyComponent.encodeChildren(context);
emptyComponent.encodeEnd(context);
}
}
// call render-after to output footers if required
renderer.renderListAfter(context, richList, columns);
out.write("</tbody>");
}
}
/**
* @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
*/
public void encodeEnd(FacesContext context, UIComponent component)
throws IOException
{
// always check for this flag - as per the spec
if (component.isRendered() == true)
{
ResponseWriter out = context.getResponseWriter();
out.write("</table>");
}
}
/**
* @see javax.faces.render.Renderer#getRendersChildren()
*/
public boolean getRendersChildren()
{
// we are responsible for rendering our child components
// this renderer is a valid use of this mode - it can render the various
// column descriptors as a number of different list view types e.g.
// details, icons, list etc.
return true;
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class to implement a Details view for the RichList component
*
* @author kevinr
*/
public static class DetailsViewRenderer implements IRichListRenderer
{
public static final String VIEWMODEID = "details";
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#getViewModeID()
*/
public String getViewModeID()
{
return VIEWMODEID;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListBefore(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[])
*/
public void renderListBefore(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
// render column headers as labels
out.write("<tr");
outputAttribute(out, richList.getAttributes().get("headerStyleClass"), "class");
out.write('>');
for (int i=0; i<columns.length; i++)
{
UIColumn column = columns[i];
if (column.isRendered() == true)
{
// render column header tag
out.write("<th");
outputAttribute(out, column.getAttributes().get("width"), "width");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
// output the header facet if any
UIComponent header = column.getHeader();
if (header != null)
{
header.encodeBegin(context);
header.encodeChildren(context);
header.encodeEnd(context);
}
// we don't render child controls for the header row
out.write("</th>");
}
}
out.write("</tr>");
this.rowIndex = 0;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListRow(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[], java.lang.Object)
*/
public void renderListRow(FacesContext context, UIRichList richList, UIColumn[] columns, Object row)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
// output row or alt style row if set
out.write("<tr");
String rowStyle = (String)richList.getAttributes().get("rowStyleClass");
String altStyle = (String)richList.getAttributes().get("altRowStyleClass");
if (altStyle != null && (this.rowIndex++ & 1) == 1)
{
rowStyle = altStyle;
}
outputAttribute(out, rowStyle, "class");
out.write('>');
// find the actions column if it exists
UIColumn actionsColumn = null;
for (int i=0; i<columns.length; i++)
{
if (columns[i].isRendered() == true && columns[i].getActions() == true)
{
actionsColumn = columns[i];
break;
}
}
// output each column in turn and render all children
boolean renderedFirst = false;
for (int i=0; i<columns.length; i++)
{
UIColumn column = columns[i];
if (column.isRendered() == true)
{
out.write("<td");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
// for details view, we show the small column icon for the first column
if (renderedFirst == false)
{
UIComponent smallIcon = column.getSmallIcon();
if (smallIcon != null)
{
smallIcon.encodeBegin(context);
smallIcon.encodeChildren(context);
smallIcon.encodeEnd(context);
out.write("&nbsp;");
}
renderedFirst = true;
}
if (column.getChildCount() != 0)
{
if (column == actionsColumn)
{
out.write("<nobr>");
}
// allow child controls inside the columns to render themselves
Utils.encodeRecursive(context, column);
if (column == actionsColumn)
{
out.write("</nobr>");
}
}
out.write("</td>");
}
}
out.write("</tr>");
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListAfter(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[])
*/
public void renderListAfter(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
out.write("<tr><td colspan=99 align=right>");
for (Iterator i=richList.getChildren().iterator(); i.hasNext(); /**/)
{
// output all remaining child components that are not UIColumn
UIComponent child = (UIComponent)i.next();
if (child instanceof UIColumn == false)
{
Utils.encodeRecursive(context, child);
}
}
out.write("</td></tr>");
}
private int rowIndex = 0;
}
/**
* Class to implement a List view for the RichList component
*
* @author kevinr
*/
public static class ListViewRenderer implements IRichListRenderer
{
// maximum displayable textual lines within a single item cell
private final static int MAX_DISPLAYABLE_LINES = 3;
private final static String END_ROW_SEPARATOR = "</tr><tr><td colspan=10><div style='padding:3px'></div></td></tr>";
private final static String COLUMN_SPACER = "<td><div style='padding-left:8px'></div></td>";
public static final String VIEWMODEID = "list";
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#getViewModeID()
*/
public String getViewModeID()
{
return VIEWMODEID;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListBefore(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[])
*/
public void renderListBefore(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
// render column headers as labels
// TODO: add "showHeaders" to RichList to allow hiding of header facets for some view modes
/*
out.write("<tr");
outputAttribute(out, richList.getAttributes().get("headerStyleClass"), "class");
out.write('>');
for (int i=0; i<columns.length; i++)
{
UIColumn column = columns[i];
if (column.isRendered() == true)
{
out.write("<th");
outputAttribute(out, column.getAttributes().get("width"), "width");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
// output the header facet if any
UIComponent header = column.getHeader();
if (header != null)
{
header.encodeBegin(context);
header.encodeChildren(context);
header.encodeEnd(context);
}
}
// we don't render child controls for the header row
out.write("</th>");
}
out.write("</tr>");
*/
this.rowIndex = 0;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListRow(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[], java.lang.Object)
*/
public void renderListRow(FacesContext context, UIRichList richList, UIColumn[] columns, Object row) throws IOException
{
ResponseWriter out = context.getResponseWriter();
// start new row if we are on an even column in this view
// we show 2 columns, left to right
String rowStyle = (String)richList.getAttributes().get("rowStyleClass");
if ((this.rowIndex & 1) == 0)
{
out.write("<tr");
outputAttribute(out, rowStyle, "class");
out.write('>');
}
// find the actions column if it exists
// and the primary column (which must exist)
UIColumn primaryColumn = null;
UIColumn actionsColumn = null;
for (int i=0; i<columns.length; i++)
{
if (columns[i].isRendered() == true)
{
if (columns[i].getPrimary() == true)
{
primaryColumn = columns[i];
}
else if (columns[i].getActions() == true)
{
actionsColumn = columns[i];
}
}
}
if (primaryColumn == null)
{
logger.warn("No primary column found for RichList definition: " + richList.getId());
}
// get the icon from the primary column
out.write("<td width=50%><table cellspacing=0 cellpadding=2 border=0>");
if (primaryColumn != null)
{
UIColumn column = primaryColumn;
if (column.isRendered() == true)
{
out.write("<tr><td rowspan=10");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
// output the large icon for this column
UIComponent icon = column.getLargeIcon();
if (icon != null)
{
icon.encodeBegin(context);
icon.encodeChildren(context);
icon.encodeEnd(context);
}
out.write("</td>");
// start the next cell which contains the first column component
out.write("<td width=100%");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
if (column.getChildCount() != 0)
{
// allow child controls inside the column to render themselves
Utils.encodeRecursive(context, column);
}
out.write("</td>");
// output actions column if any
if (actionsColumn != null)
{
out.write("<td");
outputAttribute(out, actionsColumn.getAttributes().get("style"), "style");
outputAttribute(out, actionsColumn.getAttributes().get("styleClass"), "class");
out.write("><nobr>");
if (actionsColumn.getChildCount() != 0)
{
// allow child controls inside the columns to render themselves
Utils.encodeRecursive(context, actionsColumn);
}
out.write("</nobr></td>");
}
out.write("</tr>");
}
}
// render remaining columns as lines of data up to a max display limit
for (int i = 0; i < columns.length; i++)
{
UIColumn column = columns[i];
int count = 1;
if (column.isRendered() == true && count < MAX_DISPLAYABLE_LINES &&
column.getActions() == false && column.getPrimary() == false)
{
// output row or alt style row if set
out.write("<tr valign=top");
outputAttribute(out, rowStyle, "class");
out.write("><td colspan=2"); // render into above actions column
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
if (column.getChildCount() != 0)
{
// allow child controls inside the columns to render themselves
Utils.encodeRecursive(context, column);
}
// end this cell and end row
out.write("</td></tr>");
count++;
}
}
out.write("</table></td>");
if ((this.rowIndex & 1) == 1)
{
// end row and output a blank padding row/div
out.write(END_ROW_SEPARATOR);
}
else
{
out.write(COLUMN_SPACER);
}
this.rowIndex++;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListAfter(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[])
*/
public void renderListAfter(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
// finish last row if required (we used an open-ended column rendering algorithm)
if ( ((this.rowIndex-1) & 1) != 1)
{
out.write(END_ROW_SEPARATOR);
}
out.write("<tr><td colspan=99 align=right>");
for (Iterator i=richList.getChildren().iterator(); i.hasNext(); /**/)
{
// output all remaining child components that are not UIColumn
UIComponent child = (UIComponent)i.next();
if (child instanceof UIColumn == false)
{
Utils.encodeRecursive(context, child);
}
}
out.write("</td></tr>");
}
private int rowIndex = 0;
}
/**
* Class to implement an Icon view for the RichList component
*
* @author kevinr
*/
public static class IconViewRenderer implements IRichListRenderer
{
// number of vertical columns to render before starting new row
private final static int COLUMNS = 3;
// calculation for percentage of table row per column
private final static String COLUMN_PERCENT = Integer.toString(100/COLUMNS) + "%";
// maximum displayable textual lines within a single item cell
private final static int MAX_DISPLAYABLE_LINES = 3;
private final static String END_ROW_SEPARATOR = "</tr><tr><td colspan=10><div style='padding:3px'></div></td></tr>";
public static final String VIEWMODEID = "icons";
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#getViewModeID()
*/
public String getViewModeID()
{
return VIEWMODEID;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListBefore(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[])
*/
public void renderListBefore(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException
{
// no headers for this renderer
this.rowIndex = 0;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListRow(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[], java.lang.Object)
*/
public void renderListRow(FacesContext context, UIRichList richList, UIColumn[] columns, Object row)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
// start new row as per number of columns in this icon view
if (this.rowIndex % COLUMNS == 0)
{
out.write("<tr");
outputAttribute(out, richList.getAttributes().get("rowStyleClass"), "class");
out.write('>');
}
// find primary column (which must exist)
UIColumn primaryColumn = null;
for (int i=0; i<columns.length; i++)
{
if (columns[i].isRendered() == true && columns[i].getPrimary() == true)
{
primaryColumn = columns[i];
break;
}
}
if (primaryColumn == null)
{
logger.warn("No primary column found for RichList definition: " + richList.getId());
}
// output primary column as the icon label
out.write("<td width=");
out.write(COLUMN_PERCENT);
out.write("><table cellspacing=0 cellpadding=2 border=0>");
if (primaryColumn != null)
{
UIColumn column = primaryColumn;
if (column.isRendered() == true)
{
out.write("<tr><td rowspan=10");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
// output the large icon for this column
UIComponent largeIcon = column.getLargeIcon();
if (largeIcon != null)
{
largeIcon.encodeBegin(context);
largeIcon.encodeChildren(context);
largeIcon.encodeEnd(context);
}
out.write("</td>");
// start the next cell which contains the first column component
out.write("<td");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
if (column.getChildCount() != 0)
{
// allow child controls inside the columns to render themselves
Utils.encodeRecursive(context, column);
}
out.write("</td></tr>");
}
}
// render remaining columns as lines of data up to a max display limit
for (int i=0; i<columns.length; i++)
{
UIColumn column = columns[i];
int count = 1;
if (column.isRendered() == true && column.getPrimary() == false &&
(count < MAX_DISPLAYABLE_LINES || column.getActions() == true) )
{
out.write("<tr><td");
outputAttribute(out, column.getAttributes().get("style"), "style");
outputAttribute(out, column.getAttributes().get("styleClass"), "class");
out.write('>');
if (column.getChildCount() != 0)
{
// allow child controls inside the columns to render themselves
Utils.encodeRecursive(context, column);
}
out.write("</td></tr>");
count++;
}
}
out.write("</table></td>");
if (this.rowIndex % COLUMNS == COLUMNS-1)
{
// end row and output a blank padding row/div
out.write(END_ROW_SEPARATOR);
}
this.rowIndex++;
}
/**
* @see org.alfresco.web.ui.common.renderer.data.IRichListRenderer#renderListAfter(javax.faces.context.FacesContext, org.alfresco.web.ui.common.component.data.UIColumn[])
*/
public void renderListAfter(FacesContext context, UIRichList richList, UIColumn[] columns)
throws IOException
{
ResponseWriter out = context.getResponseWriter();
// finish last row if required (we used an open-ended column rendering algorithm)
if ((this.rowIndex-1) % COLUMNS != COLUMNS-1)
{
out.write(END_ROW_SEPARATOR);
}
out.write("<tr><td colspan=99 align=right>");
for (Iterator i=richList.getChildren().iterator(); i.hasNext(); /**/)
{
// output all remaining child components that are not UIColumn
UIComponent child = (UIComponent)i.next();
if (child instanceof UIColumn == false)
{
Utils.encodeRecursive(context, child);
}
}
out.write("</td></tr>");
}
private int rowIndex = 0;
}
private static Log logger = LogFactory.getLog(RichListRenderer.class);
}

View File

@@ -0,0 +1,211 @@
/*
* 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.tag;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
/**
* @author kevinr
*/
public class ActionLinkTag extends HtmlComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.ActionLink";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return "org.alfresco.faces.ActionLinkRenderer";
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setActionProperty((UICommand)component, this.action);
setActionListenerProperty((UICommand)component, this.actionListener);
setStringProperty(component, "image", this.image);
setBooleanProperty(component, "showLink", this.showLink);
setStringProperty(component, "verticalAlign", this.verticalAlign);
setIntProperty(component, "padding", this.padding);
setStringProperty(component, "href", this.href);
setStringProperty(component, "value", this.value);
setStringProperty(component, "target", this.target);
setStringProperty(component, "onclick", this.onclick);
// TODO: Add image width/height properties
}
/**
* @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release()
*/
public void release()
{
super.release();
this.value = null;
this.action = null;
this.actionListener = null;
this.image = null;
this.showLink = null;
this.verticalAlign = null;
this.padding = null;
this.href = null;
this.target = null;
this.onclick = null;
}
/**
* Set the value
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
/**
* Set the action
*
* @param action the action
*/
public void setAction(String action)
{
this.action = action;
}
/**
* Set the actionListener
*
* @param actionListener the actionListener
*/
public void setActionListener(String actionListener)
{
this.actionListener = actionListener;
}
/**
* Set the image
*
* @param image the image
*/
public void setImage(String image)
{
this.image = image;
}
/**
* Set the showLink
*
* @param showLink the showLink
*/
public void setShowLink(String showLink)
{
this.showLink = showLink;
}
/**
* Set the vertical alignment value
*
* @param verticalAlign the vertical alignment value
*/
public void setVerticalAlign(String verticalAlign)
{
this.verticalAlign = verticalAlign;
}
/**
* Set the padding in pixels
*
* @param padding the padding in pixels
*/
public void setPadding(String padding)
{
this.padding = padding;
}
/**
* Set the href to use instead of a JSF action
*
* @param href the href
*/
public void setHref(String href)
{
this.href = href;
}
/**
* Set the target
*
* @param target the target
*/
public void setTarget(String target)
{
this.target = target;
}
/**
* Sets the onclick handler
*
* @param onclick The onclick handler
*/
public void setOnclick(String onclick)
{
this.onclick = onclick;
}
/** the target */
private String target;
/** the padding in pixels */
private String padding;
/** the vertical alignment value */
private String verticalAlign;
/** the value (text to display) */
private String value;
/** the action */
private String action;
/** the actionListener */
private String actionListener;
/** the image */
private String image;
/** the showLink boolean */
private String showLink;
/** the href link */
private String href;
/** the onclick handler */
private String onclick;
}

View File

@@ -0,0 +1,221 @@
/*
* 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.tag;
import javax.faces.FacesException;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.webapp.UIComponentTag;
import org.alfresco.web.ui.common.ConstantMethodBinding;
/**
* @author Kevin Roast
*/
public abstract class BaseComponentTag extends UIComponentTag
{
/**
* Helper to set an action property into a command component
*
* @param command Command component
* @param action The action method binding or outcome to set
*/
protected void setActionProperty(UICommand command, String action)
{
if (action != null)
{
if (isValueReference(action))
{
MethodBinding vb = getFacesContext().getApplication().createMethodBinding(action, null);
command.setAction(vb);
}
else
{
MethodBinding vb = new ConstantMethodBinding(action);
command.setAction(vb);
}
}
}
/**
* Helper to set an action listener property into a command component
*
* @param command Command component
* @param actionListener Action listener method binding
*/
protected void setActionListenerProperty(UICommand command, String actionListener)
{
if (actionListener != null)
{
if (isValueReference(actionListener))
{
MethodBinding vb = getFacesContext().getApplication().createMethodBinding(actionListener, ACTION_CLASS_ARGS);
command.setActionListener(vb);
}
else
{
throw new FacesException("Action listener method binding incorrectly specified: " + actionListener);
}
}
}
/**
* Helper method to set a String property value into the component.
* Respects the possibility that the property value is a Value Binding.
*
* @param component UIComponent
* @param name property string name
* @param value property string value
*/
protected void setStringProperty(UIComponent component, String name, String value)
{
if (value != null)
{
if (isValueReference(value))
{
ValueBinding vb = getFacesContext().getApplication().createValueBinding(value);
component.setValueBinding(name, vb);
}
else
{
component.getAttributes().put(name, value);
}
}
}
/**
* Helper method to set a String value property into the component.
* Assumes the that the property value can only be a Value Binding.
*
* @param component UIComponent
* @param name property string name
* @param value property string value binding
*/
protected void setStringBindingProperty(UIComponent component, String name, String value)
{
if (value != null)
{
if (isValueReference(value))
{
ValueBinding vb = getFacesContext().getApplication().createValueBinding(value);
component.setValueBinding(name, vb);
}
else
{
throw new IllegalArgumentException("Property: '" + name + "' must be a value binding expression.");
}
}
}
/**
* Helper method to set a static String property into the component.
* Assumes the that the property value can only be a static string value.
*
* @param component UIComponent
* @param name property string name
* @param value property string static value
*/
protected void setStringStaticProperty(UIComponent component, String name, String value)
{
if (value != null)
{
component.getAttributes().put(name, value);
}
}
/**
* Helper method to set a String property as an Integer value into the component.
* Respects the possibility that the property value is a Value Binding.
*
* @param component UIComponent
* @param name property string name
* @param value property string value (an Integer will be created)
*/
protected void setIntProperty(UIComponent component, String name, String value)
{
if (value != null)
{
if (isValueReference(value))
{
ValueBinding vb = getFacesContext().getApplication().createValueBinding(value);
component.setValueBinding(name, vb);
}
else
{
try
{
component.getAttributes().put(name, Integer.valueOf(value));
}
catch (NumberFormatException ne)
{
throw new RuntimeException("Was expecting Int value for property '" + name + "' but passed value: " + value);
}
}
}
}
protected void setIntStaticProperty(UIComponent component, String name, String value)
{
if (value != null)
{
try
{
component.getAttributes().put(name, Integer.valueOf(value));
}
catch (NumberFormatException ne)
{
throw new RuntimeException("Was expecting Int value for property '" + name + "' but passed value: " + value);
}
}
}
/**
* Helper method to set a String property as an Boolean value into the component.
* Respects the possibility that the property value is a Value Binding.
*
* @param component UIComponent
* @param name property string name
* @param value property string value (a Boolean will be created)
*/
protected void setBooleanProperty(UIComponent component, String name, String value)
{
if (value != null)
{
if (isValueReference(value))
{
ValueBinding vb = getFacesContext().getApplication().createValueBinding(value);
component.setValueBinding(name, vb);
}
else
{
component.getAttributes().put(name, Boolean.valueOf(value));
}
}
}
protected void setBooleanStaticProperty(UIComponent component, String name, String value)
{
if (value != null)
{
component.getAttributes().put(name, Boolean.valueOf(value));
}
}
protected final static Class ACTION_CLASS_ARGS[] = {javax.faces.event.ActionEvent.class};
}

View File

@@ -0,0 +1,47 @@
/*
* 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.tag;
import javax.faces.convert.Converter;
import javax.faces.webapp.ConverterTag;
import javax.servlet.jsp.JspException;
import org.alfresco.web.ui.common.converter.BooleanLabelConverter;
/**
* Allows the BooleanLabelConverter component to be used on JSP pages
*
* @author gavinc
*/
public class BooleanLabelConverterTag extends ConverterTag
{
/**
* Default Constructor
*/
public BooleanLabelConverterTag()
{
setConverterId(BooleanLabelConverter.CONVERTER_ID);
}
/**
* @see javax.faces.webapp.ConverterTag#createConverter()
*/
protected Converter createConverter() throws JspException
{
return (BooleanLabelConverter)super.createConverter();
}
}

View File

@@ -0,0 +1,151 @@
/*
* 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.tag;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
/**
* @author kevinr
*/
public class BreadcrumbTag extends HtmlComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.Breadcrumb";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return "org.alfresco.faces.BreadcrumbRenderer";
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setActionProperty((UICommand)component, this.action);
setActionListenerProperty((UICommand)component, this.actionListener);
setStringProperty(component, "separator", this.separator);
setBooleanProperty(component, "showRoot", this.showRoot);
setBooleanProperty(component, "immediate", this.immediate);
setStringProperty(component, "value", this.value);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.action = null;
this.actionListener = null;
this.separator = ">";
this.showRoot = "true";
this.immediate = null;
this.value = null;
}
/**
* Set the action
*
* @param action the action
*/
public void setAction(String action)
{
this.action = action;
}
/**
* Set the actionListener
*
* @param actionListener the actionListener
*/
public void setActionListener(String actionListener)
{
this.actionListener = actionListener;
}
/**
* Set the separator
*
* @param separator the separator
*/
public void setSeparator(String separator)
{
this.separator = separator;
}
/**
* Set the show root value
*
* @param showRoot the showRoot
*/
public void setShowRoot(String showRoot)
{
this.showRoot = showRoot;
}
/**
* Set if the action event fired is immediate
*
* @param immediate true if the action event fired is immediate
*/
public void setImmediate(String immediate)
{
this.immediate = immediate;
}
/**
* Set the value. The value for a breadcrumb is either a '/' separated String path
* or a List of IBreadcrumb handler instances.
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
/** the value */
private String value;
/** the action */
private String action;
/** the actionListener */
private String actionListener;
/** the separator */
private String separator = ">";
/** the showRoot value */
private String showRoot = "true";
/** true if the action event fired is immediate */
private String immediate;
}

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.tag;
import javax.faces.convert.Converter;
import javax.faces.webapp.ConverterTag;
import javax.servlet.jsp.JspException;
import org.alfresco.web.ui.common.converter.ByteSizeConverter;
/**
* @author Kevin Roast
*/
public class ByteSizeConverterTag extends ConverterTag
{
/**
* Default Constructor
*/
public ByteSizeConverterTag()
{
setConverterId(ByteSizeConverter.CONVERTER_ID);
}
/**
* @see javax.faces.webapp.ConverterTag#createConverter()
*/
protected Converter createConverter() throws JspException
{
return (ByteSizeConverter)super.createConverter();
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
public class ErrorsTag extends HtmlComponentTag
{
private String message;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "javax.faces.Messages";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return "org.alfresco.faces.Errors";
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "message", this.message);
}
/**
* @param message Sets the message to display
*/
public void setMessage(String message)
{
this.message = message;
}
}

View File

@@ -0,0 +1,242 @@
/*
* 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.tag;
import javax.faces.FacesException;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import org.alfresco.web.ui.common.component.UIGenericPicker;
/**
* @author Kevin Roast
*/
public class GenericPickerTag extends BaseComponentTag
{
private final static Class QUERYCALLBACK_CLASS_ARGS[] = {int.class, String.class};
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.GenericPicker";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setBooleanProperty(component, "showFilter", this.showFilter);
setBooleanProperty(component, "showContains", this.showContains);
setBooleanProperty(component, "showAddButton", this.showAddButton);
setBooleanProperty(component, "filterRefresh", this.filterRefresh);
setStringProperty(component, "addButtonLabel", this.addButtonLabel);
setActionProperty((UICommand)component, this.action);
setActionListenerProperty((UICommand)component, this.actionListener);
setIntProperty(component, "width", this.width);
setIntProperty(component, "height", this.height);
setStringBindingProperty(component, "filters", this.filters);
if (queryCallback != null)
{
if (isValueReference(queryCallback))
{
MethodBinding b = getFacesContext().getApplication().createMethodBinding(queryCallback, QUERYCALLBACK_CLASS_ARGS);
((UIGenericPicker)component).setQueryCallback(b);
}
else
{
throw new FacesException("Query Callback method binding incorrectly specified: " + queryCallback);
}
}
}
/**
* @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release()
*/
public void release()
{
super.release();
this.showFilter = null;
this.showContains = null;
this.showAddButton = null;
this.addButtonLabel = null;
this.action = null;
this.actionListener = null;
this.width = null;
this.height = null;
this.queryCallback = null;
this.filters = null;
this.filterRefresh = null;
}
/**
* Set the showFilter
*
* @param showFilter the showFilter
*/
public void setShowFilter(String showFilter)
{
this.showFilter = showFilter;
}
/**
* Set the showContains
*
* @param showContains the showContains
*/
public void setShowContains(String showContains)
{
this.showContains = showContains;
}
/**
* Set the showAddButton
*
* @param showAddButton the showAddButton
*/
public void setShowAddButton(String showAddButton)
{
this.showAddButton = showAddButton;
}
/**
* Set the addButtonLabel
*
* @param addButtonLabel the addButtonLabel
*/
public void setAddButtonLabel(String addButtonLabel)
{
this.addButtonLabel = addButtonLabel;
}
/**
* Set the action
*
* @param action the action
*/
public void setAction(String action)
{
this.action = action;
}
/**
* Set the actionListener
*
* @param actionListener the actionListener
*/
public void setActionListener(String actionListener)
{
this.actionListener = actionListener;
}
/**
* Set the width
*
* @param width the width
*/
public void setWidth(String width)
{
this.width = width;
}
/**
* Set the height
*
* @param height the height
*/
public void setHeight(String height)
{
this.height = height;
}
/**
* Set the queryCallback
*
* @param queryCallback the queryCallback
*/
public void setQueryCallback(String queryCallback)
{
this.queryCallback = queryCallback;
}
/**
* Set the filters
*
* @param filters the filters
*/
public void setFilters(String filters)
{
this.filters = filters;
}
/**
* Set the filterRefresh
*
* @param filterRefresh the filterRefresh
*/
public void setFilterRefresh(String filterRefresh)
{
this.filterRefresh = filterRefresh;
}
/** the filterRefresh */
private String filterRefresh;
/** the filters */
private String filters;
/** the queryCallback */
private String queryCallback;
/** the showFilter */
private String showFilter;
/** the showContains */
private String showContains;
/** the showAddButton */
private String showAddButton;
/** the addButtonLabel */
private String addButtonLabel;
/** the action */
private String action;
/** the actionListener */
private String actionListener;
/** the width */
private String width;
/** the height */
private String height;
}

View File

@@ -0,0 +1,91 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
/**
* Base class for tags that represent HTML components.
*
* @author kevinr
*/
public abstract class HtmlComponentTag extends BaseComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "style", this.style);
setStringProperty(component, "styleClass", this.styleClass);
setStringProperty(component, "tooltip", this.tooltip);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.style = null;
this.styleClass = null;
this.tooltip = null;
}
/**
* Set the style
*
* @param style the style
*/
public void setStyle(String style)
{
this.style = style;
}
/**
* Set the styleClass
*
* @param styleClass the styleClass
*/
public void setStyleClass(String styleClass)
{
this.styleClass = styleClass;
}
/**
* Set the tooltip
*
* @param tooltip the tooltip
*/
public void setTooltip(String tooltip)
{
this.tooltip = tooltip;
}
/** the tooltip */
private String tooltip;
/** the style */
private String style;
/** the CSS style class */
private String styleClass;
}

View File

@@ -0,0 +1,227 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
/**
* Tag to combine the image picker component and radio renderer
*
* @author gavinc
*/
public class ImagePickerRadioTag extends HtmlComponentTag
{
/** the labelStyle */
private String labelStyle;
/** the labelStyleClass */
private String labelStyleClass;
/** the spacing */
private String spacing;
/** the columns */
private String columns;
/** the label */
private String label;
/** the value */
private String value;
/** the image */
private String image;
/** the onclick handler */
private String onclick;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.ImagePicker";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return "org.alfresco.faces.Radio";
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "labelStyle", this.labelStyle);
setStringProperty(component, "labelStyleClass", this.labelStyleClass);
setStringProperty(component, "label", this.label);
setStringProperty(component, "value", this.value);
setStringProperty(component, "image", this.image);
setStringProperty(component, "onclick", this.onclick);
setIntProperty(component, "spacing", this.spacing);
setIntProperty(component, "columns", this.columns);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.labelStyle = null;
this.labelStyleClass = null;
this.spacing = null;
this.label = null;
this.value = null;
this.image = null;
this.columns = null;
this.onclick = null;
}
/**
* @return Returns the image.
*/
public String getImage()
{
return image;
}
/**
* @param image The image to set.
*/
public void setImage(String image)
{
this.image = image;
}
/**
* @return Returns the label.
*/
public String getLabel()
{
return label;
}
/**
* @param label The label to set.
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* @return Returns the labelStyle.
*/
public String getLabelStyle()
{
return labelStyle;
}
/**
* @param labelStyle The labelStyle to set.
*/
public void setLabelStyle(String labelStyle)
{
this.labelStyle = labelStyle;
}
/**
* @return Returns the labelStyleClass.
*/
public String getLabelStyleClass()
{
return labelStyleClass;
}
/**
* @param labelStyleClass The labelStyleClass to set.
*/
public void setLabelStyleClass(String labelStyleClass)
{
this.labelStyleClass = labelStyleClass;
}
/**
* @return Returns the spacing.
*/
public String getSpacing()
{
return spacing;
}
/**
* @param spacing The spacing to set.
*/
public void setSpacing(String spacing)
{
this.spacing = spacing;
}
/**
* @return Returns the value.
*/
public String getValue()
{
return value;
}
/**
* @param value The value to set.
*/
public void setValue(String value)
{
this.value = value;
}
/**
* @return Returns the columns.
*/
public String getColumns()
{
return columns;
}
/**
* @param columns The columns to set.
*/
public void setColumns(String columns)
{
this.columns = columns;
}
/**
* @return Returns the onclick.
*/
public String getOnclick()
{
return onclick;
}
/**
* @param onclick The onclick to set.
*/
public void setOnclick(String onclick)
{
this.onclick = onclick;
}
}

View File

@@ -0,0 +1,135 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
/**
* @author kevinr
*
* Tag handler for an Input UI Component specific for Date input.
*
* This tag collects the user params needed to specify an Input component to allow
* the user to enter a date. It specifies the renderer as below to be our Date
* specific renderer. This renderer is configured in the faces-config.xml.
*/
public class InputDatePickerTag extends HtmlComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
// we are require an Input component to manage our state
// this is just a convention name Id - not an actual class
return "javax.faces.Input";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// the renderer type is a convention name Id - not an actual class
// see the <render-kit> in faces-config.xml
return "org.alfresco.faces.DatePickerRenderer";
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.startYear = "1990";
this.yearCount = "10";
this.value = null;
this.showTime = null;
this.disabled = null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
// set the properties of tag into the component
setIntProperty(component, "startYear", this.startYear);
setIntProperty(component, "yearCount", this.yearCount);
setStringProperty(component, "value", this.value);
setBooleanProperty(component, "showTime", this.showTime);
setBooleanProperty(component, "disabled", this.disabled);
}
/**
* Set the value
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
/**
* Set the startYear
*
* @param startYear the startYear
*/
public void setStartYear(String startYear)
{
this.startYear = startYear;
}
/**
* Set the yearCount
*
* @param yearCount the yearCount
*/
public void setYearCount(String yearCount)
{
this.yearCount = yearCount;
}
/**
* Determines whether the time is rendered
*
* @param showTime true to allow the time to be edited
*/
public void setShowTime(String showTime)
{
this.showTime = showTime;
}
/**
* Sets whether the component should be rendered in a disabled state
*
* @param disabled true to render the component in a disabled state
*/
public void setDisabled(String disabled)
{
this.disabled = disabled;
}
private String startYear = "1990";
private String yearCount = "10";
private String value = null;
private String showTime = null;
private String disabled = null;
}

View File

@@ -0,0 +1,133 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
/**
* @author kevinr
*/
public class ListItemTag extends BaseComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.ListItem";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// this component is rendered by its parent container
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "tooltip", this.tooltip);
setStringProperty(component, "label", this.label);
setStringProperty(component, "image", this.image);
setStringProperty(component, "value", this.value);
setBooleanProperty(component, "disabled", this.disabled);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.tooltip = null;
this.label = null;
this.image = null;
this.value = null;
this.disabled = null;
}
/**
* Set the tooltip
*
* @param tooltip the tooltip
*/
public void setTooltip(String tooltip)
{
this.tooltip = tooltip;
}
/**
* Set the label
*
* @param label the label
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* Set the image
*
* @param image the image
*/
public void setImage(String image)
{
this.image = image;
}
/**
* Set the value to be selected initially
*
* @param value the value to be selected initially
*/
public void setValue(String value)
{
this.value = value;
}
/**
* Set the disabled flag
*
* @param disabled true to set this item as disabled
*/
public void setDisabled(String disabled)
{
this.disabled = disabled;
}
/** the tooltip */
private String tooltip;
/** the label */
private String label;
/** the image */
private String image;
/** the value to be selected initially */
private String value;
/** the disabled flag */
private String disabled;
}

View File

@@ -0,0 +1,74 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
/**
* Tag used to place the ListItems component on a JSP page
*
* @author gavinc
*/
public class ListItemsTag extends BaseComponentTag
{
private String value;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.ListItems";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// this component is rendered by its parent container
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringBindingProperty(component, "value", this.value);
}
/**
* @param value Sets the value
*/
public void setValue(String value)
{
this.value = value;
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.value = null;
}
}

View File

@@ -0,0 +1,134 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
/**
* @author kevinr
*/
public class MenuTag extends HtmlComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.Menu";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// the component is self renderering
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "label", this.label);
setStringProperty(component, "image", this.image);
setStringProperty(component, "menuStyle", this.menuStyle);
setStringProperty(component, "menuStyleClass", this.menuStyleClass);
setIntProperty(component, "itemSpacing", this.itemSpacing);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.label = null;
this.image = null;
this.menuStyle = null;
this.menuStyleClass = null;
this.itemSpacing = null;
}
/**
* Set the label
*
* @param label the label
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* Set the image
*
* @param image the image
*/
public void setImage(String image)
{
this.image = image;
}
/**
* Set the menuStyle
*
* @param menuStyle the menuStyle
*/
public void setMenuStyle(String menuStyle)
{
this.menuStyle = menuStyle;
}
/**
* Set the menuStyleClass
*
* @param menuStyleClass the menuStyleClass
*/
public void setMenuStyleClass(String menuStyleClass)
{
this.menuStyleClass = menuStyleClass;
}
/**
* Set the itemSpacing
*
* @param itemSpacing the itemSpacing
*/
public void setItemSpacing(String itemSpacing)
{
this.itemSpacing = itemSpacing;
}
/** the menuStyle */
private String menuStyle;
/** the menuStyleClass */
private String menuStyleClass;
/** the itemSpacing */
private String itemSpacing;
/** the image */
private String image;
/** the label */
private String label;
}

View File

@@ -0,0 +1,389 @@
/*
* 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.tag;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
/**
* @author kevinr
*/
public class ModeListTag extends HtmlComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.ModeList";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return "org.alfresco.faces.ModeListRenderer";
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setActionProperty((UICommand)component, this.action);
setActionListenerProperty((UICommand)component, this.actionListener);
setStringProperty(component, "labelStyle", this.labelStyle);
setStringProperty(component, "labelStyleClass", this.labelStyleClass);
setStringProperty(component, "itemStyle", this.itemStyle);
setStringProperty(component, "itemStyleClass", this.itemStyleClass);
setStringProperty(component, "disabledStyle", this.disabledStyle);
setStringProperty(component, "disabledStyleClass", this.disabledStyleClass);
setStringProperty(component, "itemLinkStyle", this.itemLinkStyle);
setStringProperty(component, "itemLinkStyleClass", this.itemLinkStyleClass);
setStringProperty(component, "selectedStyle", this.selectedStyle);
setStringProperty(component, "selectedStyleClass", this.selectedStyleClass);
setStringProperty(component, "selectedLinkStyle", this.selectedLinkStyle);
setStringProperty(component, "selectedLinkStyleClass", this.selectedLinkStyleClass);
setStringProperty(component, "selectedImage", this.selectedImage);
setIntProperty(component, "itemSpacing", this.itemSpacing);
setIntProperty(component, "iconColumnWidth", this.iconColumnWidth);
setIntProperty(component, "width", this.width);
setBooleanProperty(component, "horizontal", this.horizontal);
setBooleanProperty(component, "disabled", this.disabled);
setStringProperty(component, "label", this.label);
setStringProperty(component, "value", this.value);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.labelStyle = null;
this.labelStyleClass = null;
this.itemStyle = null;
this.itemStyleClass = null;
this.itemLinkStyle = null;
this.itemLinkStyleClass = null;
this.disabledStyle = null;
this.disabledStyleClass = null;
this.selectedStyle = null;
this.selectedStyleClass = null;
this.selectedLinkStyle = null;
this.selectedLinkStyleClass = null;
this.selectedImage = null;
this.itemSpacing = null;
this.iconColumnWidth = null;
this.horizontal = null;
this.width = null;
this.label = null;
this.action = null;
this.actionListener = null;
this.value = null;
this.disabled = null;
}
/**
* Set the itemSpacing
*
* @param itemSpacing the itemSpacing
*/
public void setItemSpacing(String itemSpacing)
{
this.itemSpacing = itemSpacing;
}
/**
* Set the iconColumnWidth
*
* @param iconColumnWidth the iconColumnWidth
*/
public void setIconColumnWidth(String iconColumnWidth)
{
this.iconColumnWidth = iconColumnWidth;
}
/**
* Set the label
*
* @param label the label
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* Set the action
*
* @param action the action
*/
public void setAction(String action)
{
this.action = action;
}
/**
* Set the actionListener
*
* @param actionListener the actionListener
*/
public void setActionListener(String actionListener)
{
this.actionListener = actionListener;
}
/**
* Set the value
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
/**
* Set the width
*
* @param width the width
*/
public void setWidth(String width)
{
this.width = width;
}
/**
* Set if this component is rendered horizontally
*
* @param horizontal true if rendered horizontally, false to render vertically
*/
public void setHorizontal(String horizontal)
{
this.horizontal = horizontal;
}
/**
* Set the labelStyle
*
* @param labelStyle the labelStyle
*/
public void setLabelStyle(String labelStyle)
{
this.labelStyle = labelStyle;
}
/**
* Set the labelStyleClass
*
* @param labelStyleClass the labelStyleClass
*/
public void setLabelStyleClass(String labelStyleClass)
{
this.labelStyleClass = labelStyleClass;
}
/**
* Set the itemStyle
*
* @param itemStyle the itemStyle
*/
public void setItemStyle(String itemStyle)
{
this.itemStyle = itemStyle;
}
/**
* Set the itemStyleClass
*
* @param itemStyleClass the itemStyleClass
*/
public void setItemStyleClass(String itemStyleClass)
{
this.itemStyleClass = itemStyleClass;
}
/**
* Set the itemLinkStyle
*
* @param itemLinkStyle the itemLinkStyle
*/
public void setItemLinkStyle(String itemLinkStyle)
{
this.itemLinkStyle = itemLinkStyle;
}
/**
* Set the itemLinkStyleClass
*
* @param itemLinkStyleClass the itemLinkStyleClass
*/
public void setItemLinkStyleClass(String itemLinkStyleClass)
{
this.itemLinkStyleClass = itemLinkStyleClass;
}
/**
* Set the selectedStyle
*
* @param selectedStyle the selectedStyle
*/
public void setSelectedStyle(String selectedStyle)
{
this.selectedStyle = selectedStyle;
}
/**
* Set the selectedStyleClass
*
* @param selectedStyleClass the selectedStyleClass
*/
public void setSelectedStyleClass(String selectedStyleClass)
{
this.selectedStyleClass = selectedStyleClass;
}
/**
* Set the selectedLinkStyle
*
* @param selectedLinkStyle the selectedLinkStyle
*/
public void setSelectedLinkStyle(String selectedLinkStyle)
{
this.selectedLinkStyle = selectedLinkStyle;
}
/**
* Set the selectedLinkStyleClass
*
* @param selectedLinkStyleClass the selectedLinkStyleClass
*/
public void setSelectedLinkStyleClass(String selectedLinkStyleClass)
{
this.selectedLinkStyleClass = selectedLinkStyleClass;
}
/**
* Set the image to show instead of the ListItem icon when the item is selected
*
* @param selectedImage the selected image
*/
public void setSelectedImage(String selectedImage)
{
this.selectedImage = selectedImage;
}
/**
* Set the disabled flag
*
* @param disabled true to disable all children
*/
public void setDisabled(String disabled)
{
this.disabled = disabled;
}
/**
* Set the disabledStyle
*
* @param disabledStyle the disabledStyle
*/
public void setDisabledStyle(String disabledStyle)
{
this.disabledStyle = disabledStyle;
}
/**
* Set the disabledStyleClass
*
* @param disabledStyleClass the disabledStyleClass
*/
public void setDisabledStyleClass(String disabledStyleClass)
{
this.disabledStyleClass = disabledStyleClass;
}
/** the disabledStyle */
private String disabledStyle;
/** the disabledStyleClass */
private String disabledStyleClass;
/** the selectedImage */
private String selectedImage;
/** the labelStyle */
private String labelStyle;
/** the labelStyleClass */
private String labelStyleClass;
/** the itemStyle */
private String itemStyle;
/** the itemStyleClass */
private String itemStyleClass;
/** the itemLinkStyle */
private String itemLinkStyle;
/** the itemLinkStyleClass */
private String itemLinkStyleClass;
/** the selectedStyle */
private String selectedStyle;
/** the selectedStyleClass */
private String selectedStyleClass;
/** the selectedLinkStyle */
private String selectedLinkStyle;
/** the selectedLinkStyleClass */
private String selectedLinkStyleClass;
/** true if rendered horizontally, false to render vertically */
private String horizontal;
/** the width */
private String width;
/** the itemSpacing */
private String itemSpacing;
/** the iconColumnWidth */
private String iconColumnWidth;
/** the label */
private String label;
/** the action */
private String action;
/** the actionListener */
private String actionListener;
/** the value */
private String value;
/** the disabled flag */
private String disabled;
}

View File

@@ -0,0 +1,74 @@
/*
* 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.tag;
import javax.faces.component.UIComponent;
/**
* Tag to place the UIOutputText component on the page
*
* @author gavinc
*/
public class OutputTextTag extends HtmlComponentTag
{
private String value;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.OutputText";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// the component is self renderering
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "value", this.value);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.value = null;
}
/**
* Set the value
*
* @param value The text
*/
public void setValue(String value)
{
this.value = value;
}
}

View File

@@ -0,0 +1,234 @@
/*
* 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.tag;
import javax.faces.FacesException;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.el.MethodBinding;
import javax.servlet.jsp.JspException;
import org.alfresco.web.ui.common.component.UIPanel;
/**
* @author kevinr
*/
public class PanelTag extends HtmlComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.Panel";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// the component is self renderering
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "label", this.label);
setStringProperty(component, "border", this.border);
setBooleanProperty(component, "progressive", this.progressive);
setStringProperty(component, "bgcolor", this.bgcolor);
setStringProperty(component, "titleBorder", this.titleBorder);
setStringProperty(component, "titleBgcolor", this.titleBgcolor);
setBooleanProperty(component, "expanded", this.expanded);
setStringProperty(component, "facetsId", this.facetsId);
if (expandedActionListener != null)
{
if (isValueReference(expandedActionListener))
{
MethodBinding vb = getFacesContext().getApplication().createMethodBinding(expandedActionListener, ACTION_CLASS_ARGS);
((UIPanel)component).setExpandedActionListener(vb);
}
else
{
throw new FacesException("Expanded Action listener method binding incorrectly specified: " + expandedActionListener);
}
}
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.label = null;
this.border = null;
this.progressive = null;
this.bgcolor = null;
this.expanded = null;
this.expandedActionListener = null;
this.facetsId = null;
}
/**
* Override this to allow the panel component to control whether child components
* are rendered by the JSP tag framework. This is a nasty solution as it requires
* a reference to the UIPanel instance and also specific knowledge of the component
* type that is created by the framework for this tag.
*
* The reason for this solution is to allow any child content (including HTML tags)
* to be displayed inside the UIPanel component without having to resort to the
* awful JSF Component getRendersChildren() mechanism - as this would force the use
* of the verbatim tags for ALL non-JSF child content!
*/
protected int getDoStartValue() throws JspException
{
UIComponent component = getComponentInstance();
if (component instanceof UIPanel)
{
if (((UIPanel)component).isExpanded() == true && component.isRendered() == true)
{
return EVAL_BODY_INCLUDE;
}
else
{
return SKIP_BODY;
}
}
return EVAL_BODY_INCLUDE;
}
/**
* Set the border
*
* @param border the border
*/
public void setBorder(String border)
{
this.border = border;
}
/**
* Set the progressive
*
* @param progressive the progressive
*/
public void setProgressive(String progressive)
{
this.progressive = progressive;
}
/**
* Set the label
*
* @param label the label
*/
public void setLabel(String label)
{
this.label = label;
}
/**
* Set the bgcolor
*
* @param bgcolor the bgcolor
*/
public void setBgcolor(String bgcolor)
{
this.bgcolor = bgcolor;
}
/**
* @param titleBgcolor The title area background color
*/
public void setTitleBgcolor(String titleBgcolor)
{
this.titleBgcolor = titleBgcolor;
}
/**
* @param titleBorder The title area border style
*/
public void setTitleBorder(String titleBorder)
{
this.titleBorder = titleBorder;
}
/**
* Set whether the panel is expanded, default is true.
*
* @param expanded the expanded flag
*/
public void setExpanded(String expanded)
{
this.expanded = expanded;
}
/**
* Set the expandedActionListener
*
* @param expandedActionListener the expandedActionListener
*/
public void setExpandedActionListener(String expandedActionListener)
{
this.expandedActionListener = expandedActionListener;
}
/**
* Set the facetsId
*
* @param facets the facetsId
*/
public void setFacetsId(String facetsId)
{
this.facetsId = facetsId;
}
/** the facets component Id */
private String facetsId;
/** the expandedActionListener */
private String expandedActionListener;
/** the expanded flag */
private String expanded;
/** the border */
private String border;
/** the progressive */
private String progressive;
/** the label */
private String label;
/** the bgcolor */
private String bgcolor;
/** the title border style */
private String titleBorder;
/** the title bgcolor */
private String titleBgcolor;
}

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.tag;
import javax.faces.component.UIComponent;
/**
* @author Kevin Roast
*/
public class StatusMessageTag extends HtmlComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.StatusMessage";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "border", this.border);
setStringProperty(component, "bgcolor", this.bgcolor);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.border = null;
this.bgcolor = null;
}
/**
* Set the border
*
* @param border the border
*/
public void setBorder(String border)
{
this.border = border;
}
/**
* Set the bgcolor
*
* @param bgcolor the bgcolor
*/
public void setBgcolor(String bgcolor)
{
this.bgcolor = bgcolor;
}
/** the border */
private String border;
/** the bgcolor */
private String bgcolor;
}

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.tag;
import javax.servlet.jsp.PageContext;
import org.alfresco.web.ui.common.converter.XMLDateConverter;
import org.apache.myfaces.taglib.core.ConvertDateTimeTag;
/**
* Tag definition to use the XMLDateConverter on a page
*
* @author gavinc
*/
public class XMLDateConverterTag extends ConvertDateTimeTag
{
public void setPageContext(PageContext context)
{
super.setPageContext(context);
setConverterId(XMLDateConverter.CONVERTER_ID);
}
}

View File

@@ -0,0 +1,142 @@
/*
* 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.tag.data;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* @author kevinr
*/
public class ColumnTag extends BaseComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.RichListColumn";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// the component is renderer by the parent
return null;
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.primary = null;
this.actions = null;
this.width = null;
this.style = null;
this.styleClass = null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setBooleanProperty(component, "primary", this.primary);
setBooleanProperty(component, "actions", this.actions);
setStringProperty(component, "width", this.width);
setStringProperty(component, "style", this.style);
setStringProperty(component, "styleClass", this.styleClass);
}
// ------------------------------------------------------------------------------
// Tag properties
/**
* Set if this is the primary column
*
* @param primary the primary if "true", otherwise false
*/
public void setPrimary(String primary)
{
this.primary = primary;
}
/**
* Set the width
*
* @param width the width
*/
public void setWidth(String width)
{
this.width = width;
}
/**
* Set the style
*
* @param style the style
*/
public void setStyle(String style)
{
this.style = style;
}
/**
* Set the styleClass
*
* @param styleClass the styleClass
*/
public void setStyleClass(String styleClass)
{
this.styleClass = styleClass;
}
/**
* Set if this is the actions column
*
* @param actions the actions if "true", otherwise false
*/
public void setActions(String actions)
{
this.actions = actions;
}
/** the actions */
private String actions;
/** the style */
private String style;
/** the styleClass */
private String styleClass;
/** the width */
private String width;
/** the primary */
private String primary;
}

View File

@@ -0,0 +1,64 @@
/*
* 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.tag.data;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.HtmlComponentTag;
/**
* @author kevinr
*/
public class DataPagerTag extends HtmlComponentTag
{
// ------------------------------------------------------------------------------
// Component methods
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.DataPager";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
// UIDataPager is self rendering
return null;
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
}
}

View File

@@ -0,0 +1,266 @@
/*
* 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.tag.data;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* @author kevinr
*/
public class RichListTag extends BaseComponentTag
{
// ------------------------------------------------------------------------------
// Component methods
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.RichList";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return "org.alfresco.faces.RichListRenderer";
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.value = null;
this.var = null;
this.initialSortColumn = null;
this.initialSortDescending = null;
this.listConfig = null;
this.viewMode = null;
this.style = null;
this.styleClass = null;
this.rowStyleClass = null;
this.altRowStyleClass = null;
this.headerStyleClass = null;
this.width = null;
this.pageSize = null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringBindingProperty(component, "value", this.value);
setStringStaticProperty(component, "var", this.var);
setStringProperty(component, "initialSortColumn", this.initialSortColumn);
setBooleanProperty(component, "initialSortDescending", this.initialSortDescending);
setStringProperty(component, "listConfig", this.listConfig);
setStringProperty(component, "viewMode", this.viewMode);
setStringProperty(component, "style", this.style);
setStringProperty(component, "styleClass", this.styleClass);
setStringProperty(component, "rowStyleClass", this.rowStyleClass);
setStringProperty(component, "altRowStyleClass", this.altRowStyleClass);
setStringProperty(component, "headerStyleClass", this.headerStyleClass);
setStringProperty(component, "width", this.width);
setIntProperty(component, "pageSize", this.pageSize);
}
// ------------------------------------------------------------------------------
// Bean implementation
/**
* Set the viewMode
*
* @param viewMode the viewMode
*/
public void setViewMode(String viewMode)
{
this.viewMode = viewMode;
}
/**
* Set the pageSize
*
* @param pageSize the pageSize
*/
public void setPageSize(String pageSize)
{
this.pageSize = pageSize;
}
/**
* Set the initialSortColumn
*
* @param initialSortColumn the initialSortColumn
*/
public void setInitialSortColumn(String initialSortColumn)
{
this.initialSortColumn = initialSortColumn;
}
/**
* Set the initialSortDescending
*
* @param initialSortDescending the initialSortDescending
*/
public void setInitialSortDescending(String initialSortDescending)
{
this.initialSortDescending = initialSortDescending;
}
/**
* Set the listConfig
*
* @param listConfig the listConfig
*/
public void setListConfig(String listConfig)
{
this.listConfig = listConfig;
}
/**
* Set the value
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
/**
* Set the var
*
* @param var the var
*/
public void setVar(String var)
{
this.var = var;
}
/**
* Set the style
*
* @param style the style
*/
public void setStyle(String style)
{
this.style = style;
}
/**
* Set the styleClass
*
* @param styleClass the styleClass
*/
public void setStyleClass(String styleClass)
{
this.styleClass = styleClass;
}
/**
* Set the the row CSS Class
*
* @param rowStyleClass the the row CSS Class
*/
public void setRowStyleClass(String rowStyleClass)
{
this.rowStyleClass = rowStyleClass;
}
/**
* Set the alternate row CSS Class
*
* @param altRowStyleClass the alternate row CSS Class
*/
public void setAltRowStyleClass(String altRowStyleClass)
{
this.altRowStyleClass = altRowStyleClass;
}
/**
* Set the width
*
* @param width the width
*/
public void setWidth(String width)
{
this.width = width;
}
/**
* Set the header row CSS Class
*
* @param headerStyleClass the header row CSS Class
*/
public void setHeaderStyleClass(String headerStyleClass)
{
this.headerStyleClass = headerStyleClass;
}
// ------------------------------------------------------------------------------
// Private data
/** the header row CSS Class */
private String headerStyleClass;
/** the row CSS Class */
private String rowStyleClass;
/** the alternate row CSS Class */
private String altRowStyleClass;
/** the style */
private String style;
/** the styleClass */
private String styleClass;
/** the width */
private String width;
/** the value */
private String value;
/** the var */
private String var;
/** the viewMode */
private String viewMode;
/** the pageSize */
private String pageSize;
/** the initialSortColumn */
private String initialSortColumn;
/** the initialSortDescending */
private String initialSortDescending;
/** the listConfig */
private String listConfig;
}

View File

@@ -0,0 +1,108 @@
/*
* 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.tag.data;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.HtmlComponentTag;
/**
* @author kevinr
*/
public class SortLinkTag extends HtmlComponentTag
{
// ------------------------------------------------------------------------------
// Component methods
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.SortLink";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.mode = null;
this.value = null;
this.label = null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "value", this.value);
setStringProperty(component, "label", this.label);
setStringProperty(component, "mode", this.mode);
}
/**
* Set the value
*
* @param value the value
*/
public void setValue(String value)
{
this.value = value;
}
/**
* Set the sorting mode (see IDataContainer constants)
*
* @param mode the sort mode
*/
public void setMode(String mode)
{
this.mode = mode;
}
/**
* Set the label
*
* @param label the label
*/
public void setLabel(String label)
{
this.label = label;
}
/** the label */
private String label;
/** the value */
private String value;
/** the sorting mode */
private String mode;
}

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.tag.debug;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.HtmlComponentTag;
/**
* Base class for all debug tags.
*
* @author gavinc
*/
public abstract class BaseDebugTag extends HtmlComponentTag
{
private String title;
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "title", this.title);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.title = null;
}
/**
* Sets the title
*
* @param title The title
*/
public void setTitle(String title)
{
this.title = title;
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.tag.debug;
/**
* Tag implementation used to place the HTTP session state component
* on a page.
*
* @author gavinc
*/
public class HttpApplicationStateTag extends BaseDebugTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.debug.HttpApplicationState";
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.tag.debug;
/**
* Tag implementation used to place the HTTP headers component
* on a page.
*
* @author gavinc
*/
public class HttpRequestHeadersTag extends BaseDebugTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.debug.HttpRequestHeaders";
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.tag.debug;
/**
* Tag implementation used to place the HTTP request params component
* on a page.
*
* @author gavinc
*/
public class HttpRequestParamsTag extends BaseDebugTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.debug.HttpRequestParams";
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.tag.debug;
/**
* Tag implementation used to place the HTTP request state component
* on a page.
*
* @author gavinc
*/
public class HttpRequestStateTag extends BaseDebugTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.debug.HttpRequestState";
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.tag.debug;
/**
* Tag implementation used to place the HTTP session state component
* on a page.
*
* @author gavinc
*/
public class HttpSessionStateTag extends BaseDebugTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.debug.HttpSessionState";
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.tag.debug;
/**
* Tag implementation used to place the system properties component
* on a page.
*
* @author gavinc
*/
public class SystemPropertiesTag extends BaseDebugTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.debug.SystemProperties";
}
}

View File

@@ -0,0 +1,86 @@
/*
* 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.tag.description;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* Tag class to allow the description component to be used on a JSP page
*
* @author gavinc
*/
public class DescriptionTag extends BaseComponentTag
{
private String controlValue;
private String text;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.Description";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "controlValue", this.controlValue);
setStringProperty(component, "text", this.text);
}
/**
* @param controlValue The value of the control this description is for
*/
public void setControlValue(String controlValue)
{
this.controlValue = controlValue;
}
/**
* @param text Sets the description text
*/
public void setText(String text)
{
this.text = text;
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.controlValue = null;
this.text = null;
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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.tag.description;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* Tag class to allow the descriptions component to be used on a JSP page
*
* @author gavinc
*/
public class DescriptionsTag extends BaseComponentTag
{
private String value;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.Descriptions";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringBindingProperty(component, "value", this.value);
}
/**
* @param value Sets the value
*/
public void setValue(String value)
{
this.value = value;
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.value = null;
}
}

View File

@@ -0,0 +1,86 @@
/*
* 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.tag.description;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* Tag class to allow the dynamic description component to be used on a JSP page
*
* @author gavinc
*/
public class DynamicDescriptionTag extends BaseComponentTag
{
private String selected;
private String functionName;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.DynamicDescription";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "selected", this.selected);
setStringStaticProperty(component, "functionName", this.functionName);
}
/**
* @param selected Sets the selected description id
*/
public void setSelected(String selected)
{
this.selected = selected;
}
/**
* @param functionName Sets the JavaScript function name
*/
public void setFunctionName(String functionName)
{
this.functionName = functionName;
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.selected = null;
this.functionName = null;
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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.tag.evaluator;
/**
* @author kevinr
*/
public class BooleanEvaluatorTag extends GenericEvaluatorTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.BooleanEvaluator";
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.tag.evaluator;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.BaseComponentTag;
/**
* @author kevinr
*/
public abstract class GenericEvaluatorTag extends BaseComponentTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public final String getRendererType()
{
// evaluator components do not use renderers
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "value", this.value);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.value = null;
}
/**
* Set the value to evaluate against
*
* @param value the value to evaluate against
*/
public void setValue(String value)
{
this.value = value;
}
/** the value to evaluate against */
private String value;
}

View File

@@ -0,0 +1,65 @@
/*
* 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.tag.evaluator;
import javax.faces.component.UIComponent;
/**
* @author kevinr
*/
public class StringEqualsEvaluatorTag extends GenericEvaluatorTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.StringEqualsEvaluator";
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringProperty(component, "condition", this.condition);
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
public void release()
{
super.release();
this.condition = null;
}
/**
* Set the condition string to test value against
*
* @param condition the condition string to test value against
*/
public void setCondition(String condition)
{
this.condition = condition;
}
/** the condition string to test value against */
private String condition;
}

View File

@@ -0,0 +1,31 @@
/*
* 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.tag.evaluator;
/**
* @author kevinr
*/
public class ValueSetEvaluatorTag extends GenericEvaluatorTag
{
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.ValueSetEvaluator";
}
}

View File

@@ -0,0 +1,35 @@
/*
* 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.repo;
/**
* @author Kevin Roast
*/
public final class RepoConstants
{
public static final String ALFRESCO_FACES_SPACE_SELECTOR = "org.alfresco.faces.SpaceSelector";
public static final String ALFRESCO_FACES_DATE_PICKER_RENDERER = "org.alfresco.faces.DatePickerRenderer";
public static final String ALFRESCO_FACES_CATEGORY_SELECTOR = "org.alfresco.faces.CategorySelector";
public static final String ALFRESCO_FACES_XMLDATA_CONVERTER = "org.alfresco.faces.XMLDataConverter";
/**
* Private constructor
*/
private RepoConstants()
{
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.repo;
/**
* Class containing well known web resource paths for images etc.
*
* @author Kevin Roast
*/
public class WebResources extends org.alfresco.web.ui.common.WebResources
{
// Image paths
public static final String IMAGE_SPACE = "/images/icons/space_small.gif";
public static final String IMAGE_CATEGORY = "/images/icons/category_small.gif";
public static final String IMAGE_REMOVE = "/images/icons/delete.gif";
public static final String IMAGE_COPY = "/images/icons/copy.gif";
public static final String IMAGE_CUT = "/images/icons/cut.gif";
public static final String IMAGE_PASTE = "/images/icons/paste.gif";
public static final String IMAGE_LOCK = "/images/icons/locked.gif";
public static final String IMAGE_LOCK_OWNER = "/images/icons/locked_owner.gif";
public static final String IMAGE_PERSON = "/images/icons/person.gif";
public static final String IMAGE_GROUP = "/images/icons/group.gif";
}

View File

@@ -0,0 +1,800 @@
/*
* 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.repo.component;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
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 javax.transaction.UserTransaction;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.WebResources;
/**
* Abstract component to allow the selection of a hierarchical item
*
* @author gavinc
*/
public abstract class AbstractItemSelector extends UIInput
{
private static final String MSG_GO_UP = "go_up";
private static final String MSG_OK = "ok";
private static final String MSG_CANCEL = "cancel";
private final static String OK_BUTTON = "_ok";
protected final static String OPTION = "_option";
protected final static int MODE_BEFORE_SELECTION = 0;
protected final static int MODE_INITIAL_SELECTION = 1;
protected final static int MODE_DRILLDOWN_SELECTION = 2;
protected final static int MODE_CONFIRM_SELECTION = 3;
protected final static int MODE_CANCEL_SELECTION = 4;
/** label to be displayed before a space is selected */
protected String label = null;
/** cellspacing between options */
protected Integer spacing = null;
/** what mode the component is in */
protected int mode = MODE_BEFORE_SELECTION;
/** currently browsing node id */
protected String navigationId = null;
/** id of the initially selected item, if value is not set */
protected String initialSelectionId = null;
/** Flag to show whether the component is disabled */
protected Boolean disabled;
// ------------------------------------------------------------------------------
// Component Impl
/**
* Default constructor
*/
public AbstractItemSelector()
{
// set the default renderer
setRendererType(null);
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public abstract String getFamily();
/**
* Retrieves the default label to show if none has been defined and nothing has been selected
*
* @return Default label
*/
public abstract String getDefaultLabel();
/**
* Retrieves the id of the parent node of the current navigation node
*
* @param context The Faces context
* @return Id of the parent node or null if the parent is the root
*/
public abstract String getParentNodeId(FacesContext context);
/**
* Returns a collection of child associations for the current navigation node
*
* @param context The Faces context
* @return The children
*/
public abstract Collection<ChildAssociationRef> getChildrenForNode(FacesContext context);
/**
* Returns a collection of child associations of the root
*
* @param context The Faces context
* @return The root options
*/
public abstract Collection<ChildAssociationRef> getRootChildren(FacesContext context);
/**
* @return The icon image to display next to the item links, or null for no icon
*/
public abstract String getItemIcon();
/**
* @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.spacing = (Integer)values[2];
this.mode = ((Integer)values[3]).intValue();
this.navigationId = (String)values[4];
this.initialSelectionId = (String)values[5];
this.disabled = (Boolean)values[6];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[7];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.label;
values[2] = this.spacing;
values[3] = this.mode;
values[4] = this.navigationId;
values[5] = this.initialSelectionId;
values[6] = this.disabled;
return (values);
}
/**
* @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);
int mode = this.mode;
if (value != null && value.length() != 0)
{
// break up the submitted value into it's parts
// first part is the mode the component is in
// followed by the id of the selection if we are drilling down
String id = null;
int sepIndex = value.indexOf(NamingContainer.SEPARATOR_CHAR);
if (sepIndex != -1)
{
mode = Integer.parseInt(value.substring(0, sepIndex));
if (value.length() > sepIndex + 1)
{
id = value.substring(sepIndex + 1);
}
}
else
{
mode = Integer.parseInt(value);
}
// raise an event so we can pick the changed values up later
ItemSelectorEvent event = new ItemSelectorEvent(this, mode, id);
this.queueEvent(event);
}
if (mode == MODE_CONFIRM_SELECTION)
{
// only bother to check the selection if the mode is set to MODE_AFTER_SELECTION
// see if a selection has been submitted
String selection = (String)requestMap.get(getClientId(context) + OPTION);
if (selection != null && selection.length() != 0)
{
((EditableValueHolder)this).setSubmittedValue(new NodeRef(Repository.getStoreRef(), selection));
}
}
}
/**
* @see javax.faces.component.UIInput#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof ItemSelectorEvent)
{
ItemSelectorEvent spaceEvent = (ItemSelectorEvent)event;
this.mode = spaceEvent.Mode;
this.navigationId = spaceEvent.Id;
}
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;
}
if (isDisabled())
{
// render a read-only view of the selected category (if any)
ResponseWriter out = context.getResponseWriter();
// see if there is a current value for the category
NodeRef nodeRef = (NodeRef)getSubmittedValue();
if (nodeRef == null)
{
Object val = getValue();
if (val instanceof NodeRef)
{
nodeRef = (NodeRef)val;
}
else if (val instanceof String && ((String)val).length() != 0)
{
nodeRef = new NodeRef((String)val);
}
}
// if there is a value show it's name
if (nodeRef != null)
{
NodeService service = Repository.getServiceRegistry(context).getNodeService();
out.write(Repository.getNameForNode(service, nodeRef));
}
}
else
{
// render an editable control for selecting categories
String clientId = getClientId(context);
StringBuilder buf = new StringBuilder(512);
Map attrs = this.getAttributes();
boolean showValueInHiddenField = false;
NodeRef value = null;
String image = null;
if (getItemIcon() != null)
{
image = "<span style='padding-right:4px'>" + Utils.buildImageTag(context, getItemIcon(), null, "absmiddle") + "</span>";
}
switch (this.mode)
{
case MODE_BEFORE_SELECTION:
case MODE_CONFIRM_SELECTION:
case MODE_CANCEL_SELECTION:
{
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(context, true);
tx.begin();
NodeRef submittedValue = (NodeRef)getSubmittedValue();
if (submittedValue != null)
{
value = submittedValue;
}
else
{
Object val = getValue();
if (val instanceof NodeRef)
{
value = (NodeRef)val;
}
else if (val instanceof String && ((String)val).length() != 0)
{
value = new NodeRef((String)val);
}
}
// show just the initial or current selection link
String label;
if (value == null)
{
label = getLabel();
// if the label is still null get the default from the message bundle
if (label == null)
{
label = getDefaultLabel();
}
}
else
{
label = Repository.getNameForNode(getNodeService(context), value);
showValueInHiddenField = true;
}
// output surrounding span for style purposes
buf.append("<span");
if (attrs.get("style") != null)
{
buf.append(" style=\"")
.append(attrs.get("style"))
.append('"');
}
if (attrs.get("styleClass") != null)
{
buf.append(" class=")
.append(attrs.get("styleClass"));
}
buf.append(">");
// rendering as initial selection mode means the sibilings of the selected
// item are shown instead of the children on first click in.
int theMode = MODE_INITIAL_SELECTION;
// if we have an initial selection and no value set the initial one up
if (value == null && this.getInitialSelection() != null)
{
value = new NodeRef(Repository.getStoreRef(), this.getInitialSelection());
}
// field value is whether we are picking and the current or parent Id value
String fieldValue;
if (value != null)
{
fieldValue = encodeFieldValues(theMode, value.getId());
}
else
{
fieldValue = encodeFieldValues(theMode, null);
}
buf.append("<a href='#' onclick=\"");
buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue));
buf.append('"');
if (attrs.get("nodeStyle") != null)
{
buf.append(" style=\"")
.append(attrs.get("nodeStyle"))
.append('"');
}
if (attrs.get("nodeStyleClass") != null)
{
buf.append(" class=")
.append(attrs.get("nodeStyleClass"));
}
buf.append(">")
.append(label)
.append("</a></span>");
tx.commit();
}
catch (Throwable err)
{
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
Utils.addErrorMessage(err.getMessage(), err);
}
break;
}
case MODE_DRILLDOWN_SELECTION:
case MODE_INITIAL_SELECTION:
{
// show the picker list
// get the children of the node ref to show
NodeService service = getNodeService(context);
UserTransaction tx = null;
try
{
tx = Repository.getUserTransaction(context, true);
tx.begin();
buf.append("<table border=0 cellspacing=1 cellpadding=1");
if (attrs.get("style") != null)
{
buf.append(" style=\"")
.append(attrs.get("style"))
.append('"');
}
if (attrs.get("styleClass") != null)
{
buf.append(" class=")
.append(attrs.get("styleClass"));
}
buf.append(">");
// if we are setting up the initial selection we need to get the
// parent id of the initial selection so the user can actually see
// the item when the list is rendered
if (this.mode == MODE_INITIAL_SELECTION)
{
this.navigationId = getParentNodeId(context);
}
// render "Go Up" link
if (this.navigationId != null)
{
// get the id of the parent node of the current navigation node,
// null indicates we are at the root level
String id = getParentNodeId(context);
buf.append("<tr><td></td><td>");
String upImage = Utils.buildImageTag(context, WebResources.IMAGE_GO_UP, null, "absmiddle");
// render a link to the parent node
renderNodeLink(context, id, Application.getMessage(context, MSG_GO_UP), upImage, buf);
buf.append("</td></tr>");
}
String okButtonId = clientId + OK_BUTTON;
boolean okButtonEnabled = false;
// display the children of the specified navigation node ID
if (this.navigationId != null)
{
// get a list of children for the current navigation node
Collection<ChildAssociationRef> childRefs = getChildrenForNode(context);
for (ChildAssociationRef childRef : childRefs)
{
// render each child found
String childId = childRef.getChildRef().getId();
buf.append("<tr><td><input type='radio' name='")
.append(clientId).append(OPTION).append("' value='")
.append(childId).append("'");
if (childId.equals(this.initialSelectionId))
{
buf.append(" checked");
// if any radio buttons are checked, the OK button must start enabled
okButtonEnabled = true;
// now remove the initial selection as we only need it the first time
this.initialSelectionId = null;
}
buf.append(" onclick=\"javascript:document.getElementById('")
.append(okButtonId)
.append("').disabled=false;\"");
buf.append("/></td><td>");
// get the name for the child and output as link
NodeRef childNodeRef = new NodeRef(Repository.getStoreRef(), childId);
String name = Repository.getNameForNode(service, childNodeRef);
renderNodeLink(context, childId, name, image, buf);
buf.append("</td></tr>");
}
}
else
{
// no node set - special case so show the root items
Collection<ChildAssociationRef> childRefs = getRootChildren(context);
for (ChildAssociationRef childRef : childRefs)
{
// render each root category found
String childId = childRef.getChildRef().getId();
buf.append("<tr><td><input type='radio' name='")
.append(clientId).append(OPTION).append("' value='")
.append(childId).append("'");
if (childId.equals(this.initialSelectionId))
{
buf.append(" checked");
// if any radio buttons are checked, the OK button must start enabled
okButtonEnabled = true;
// now remove the initial selection as we only need it the first time
this.initialSelectionId = null;
}
buf.append(" onclick=\"javascript:document.getElementById('")
.append(okButtonId)
.append("').disabled=false;\"");
buf.append("/></td><td>");
// get the name for the child (rather than association name)
NodeRef childNodeRef = new NodeRef(Repository.getStoreRef(), childId);
String name = Repository.getNameForNode(service, childNodeRef);
renderNodeLink(context, childId, name, image, buf);
buf.append("</td></tr>");
}
}
// render OK button
String fieldValue = encodeFieldValues(MODE_CONFIRM_SELECTION, null);
buf.append("<tr style='padding-top:4px'><td></td><td align=center>")
.append("<input type='button' ")
.append(okButtonEnabled == false ? "disabled" : "")
.append(" onclick=\"")
.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue))
.append("\" value='")
.append(Application.getMessage(context, MSG_OK))
.append("' id='")
.append(okButtonId)
.append("'>&nbsp;");
// render Cancel button
fieldValue = encodeFieldValues(MODE_CANCEL_SELECTION, null);
buf.append("<input type='button' onclick=\"")
.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue))
.append("\" value='")
.append(Application.getMessage(context, MSG_CANCEL))
.append("'></td></tr>");
buf.append("</table>");
tx.commit();
}
catch (Throwable err)
{
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
throw new RuntimeException(err);
}
break;
}
}
// output a hidden field containing the currently selected NodeRef so that JavaScript
// can be used to check the state of the component
buf.append("<input type='hidden' name='");
buf.append(clientId);
buf.append("_selected' id='");
buf.append(clientId);
buf.append("_selected' value='");
if (showValueInHiddenField)
{
buf.append(value);
}
buf.append("'/>");
context.getResponseWriter().write(buf.toString());
}
}
// ------------------------------------------------------------------------------
// 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 cell spacing value between space options. Default is 2.
*/
public Integer getSpacing()
{
ValueBinding vb = getValueBinding("spacing");
if (vb != null)
{
this.spacing = (Integer)vb.getValue(getFacesContext());
}
if (this.spacing != null)
{
return this.spacing.intValue();
}
else
{
// return default
return 2;
}
}
/**
* @param spacing The spacing to set.
*/
public void setSpacing(Integer spacing)
{
this.spacing = spacing;
}
/**
* @return Returns the initial selecttion.
*/
public String getInitialSelection()
{
ValueBinding vb = getValueBinding("initialSelection");
if (vb != null)
{
this.initialSelectionId = (String)vb.getValue(getFacesContext());
}
return this.initialSelectionId;
}
/**
* @param initialSelection The initial selection to set.
*/
public void setInitialSelection(String initialSelection)
{
this.initialSelectionId = initialSelection;
}
/**
* Determines whether the component should be rendered in a disabled state
*
* @return Returns whether the component is disabled
*/
public boolean isDisabled()
{
if (this.disabled == null)
{
ValueBinding vb = getValueBinding("disabled");
if (vb != null)
{
this.disabled = (Boolean)vb.getValue(getFacesContext());
}
}
if (this.disabled == null)
{
this.disabled = Boolean.FALSE;
}
return this.disabled;
}
/**
* Determines whether the component should be rendered in a disabled state
*
* @param disabled true to disable the component
*/
public void setDisabled(boolean disabled)
{
this.disabled = disabled;
}
// ------------------------------------------------------------------------------
// Protected helpers
/**
* We use a unique hidden field name based on our client Id.
* This is on the assumption that there won't be many selectors on screen at once!
* Also means we have less values to decode on submit.
*
* @return hidden field name
*/
protected String getHiddenFieldName()
{
return this.getClientId(getFacesContext());
}
protected String encodeFieldValues(int mode, String id)
{
if (id != null)
{
return Integer.toString(mode) + NamingContainer.SEPARATOR_CHAR + id;
}
else
{
return Integer.toString(mode);
}
}
/**
* Render a node descendant as a clickable link
*
* @param context FacesContext
* @param childRef The ChildAssocRef of the child to render an HTML link for
*
* @return HTML for a descendant link
*/
protected String renderNodeLink(FacesContext context, String id, String name, String prefix, StringBuilder buf)
{
buf.append("<a href='#' onclick=\"");
String fieldValue = encodeFieldValues(MODE_DRILLDOWN_SELECTION, id);
buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), fieldValue));
buf.append('"');
Map attrs = this.getAttributes();
if (attrs.get("nodeStyle") != null)
{
buf.append(" style=\"")
.append(attrs.get("nodeStyle"))
.append('"');
}
if (attrs.get("nodeStyleClass") != null)
{
buf.append(" class=")
.append(attrs.get("nodeStyleClass"));
}
buf.append('>');
if (prefix != null)
{
buf.append(prefix);
}
buf.append(Utils.encode(name));
buf.append("</a>");
return buf.toString();
}
/**
* Use Spring JSF integration to return the Node Service bean instance
*
* @param context FacesContext
*
* @return Node Service bean instance or throws exception if not found
*/
protected static NodeService getNodeService(FacesContext context)
{
NodeService service = Repository.getServiceRegistry(context).getNodeService();
if (service == null)
{
throw new IllegalStateException("Unable to obtain NodeService bean reference.");
}
return service;
}
/**
* Use Spring JSF integration to return the Dictionary Service bean instance
*
* @param context FacesContext
*
* @return Dictionary Service bean instance or throws exception if not found
*/
protected static DictionaryService getDictionaryService(FacesContext context)
{
DictionaryService service = Repository.getServiceRegistry(context).getDictionaryService();
if (service == null)
{
throw new IllegalStateException("Unable to obtain DictionaryService bean reference.");
}
return service;
}
/**
* Class representing the clicking of a breadcrumb element.
*/
public static class ItemSelectorEvent extends ActionEvent
{
public ItemSelectorEvent(UIComponent component, int mode, String id)
{
super(component);
Mode = mode;
Id = id;
}
public int Mode;
private String Id;
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.repo.component;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
/**
* @author Kevin Roast
*/
public interface IRepoBreadcrumbHandler extends IBreadcrumbHandler
{
/**
* Return a NodeRef relevant to this breadcrumb element, if any
*
* @return a NodeRef if relevant to the breadcrumb element, null otherwise
*/
public NodeRef getNodeRef();
}

View File

@@ -0,0 +1,137 @@
/*
* 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.repo.component;
import java.util.Collection;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.service.cmr.search.CategoryService.Depth;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.repo.WebResources;
/**
* Component to allow the selection of a category
*
* @author gavinc
*/
public class UICategorySelector extends AbstractItemSelector
{
// ------------------------------------------------------------------------------
// Component Impl
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.CategorySelector";
}
/**
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getDefaultLabel()
*/
public String getDefaultLabel()
{
return Application.getMessage(FacesContext.getCurrentInstance(), "select_category_prompt");
}
/**
* Use Spring JSF integration to return the category service bean instance
*
* @param context FacesContext
*
* @return category service bean instance or throws runtime exception if not found
*/
private static CategoryService getCategoryService(FacesContext context)
{
CategoryService service = Repository.getServiceRegistry(context).getCategoryService();
if (service == null)
{
throw new IllegalStateException("Unable to obtain CategoryService bean reference.");
}
return service;
}
/**
* Returns the parent id of the current category, or null if the parent has the category root type
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getParentNodeId(javax.faces.context.FacesContext)
*/
public String getParentNodeId(FacesContext context)
{
String id = null;
if (this.navigationId != null)
{
ChildAssociationRef parentRef = getNodeService(context).getPrimaryParent(
new NodeRef(Repository.getStoreRef(), this.navigationId));
Node parentNode = new Node(parentRef.getParentRef());
DictionaryService dd = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDictionaryService();
if (dd.isSubClass(parentNode.getType(), ContentModel.TYPE_CATEGORYROOT) == false)
{
id = parentRef.getParentRef().getId();
}
}
return id;
}
/**
* Returns the child categories of the current navigation node
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getChildrenForNode(javax.faces.context.FacesContext)
*/
public Collection<ChildAssociationRef> getChildrenForNode(FacesContext context)
{
NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), this.navigationId);
Collection<ChildAssociationRef> childRefs = getCategoryService(context).getChildren(nodeRef,
CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.IMMEDIATE);
return childRefs;
}
/**
* Returns the root categories
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getRootChildren(javax.faces.context.FacesContext)
*/
public Collection<ChildAssociationRef> getRootChildren(FacesContext context)
{
return getCategoryService(context).getCategories(Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, Depth.IMMEDIATE);
}
/**
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getItemIcon()
*/
public String getItemIcon()
{
return WebResources.IMAGE_CATEGORY;
}
}

View File

@@ -0,0 +1,405 @@
/*
* 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.repo.component;
import java.io.IOException;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
import org.alfresco.web.ui.repo.WebResources;
/**
* @author Kevin Roast
*/
public class UILockIcon extends SelfRenderingComponent
{
private static final String MSG_LOCKED_YOU = "locked_you";
private static final String MSG_LOCKED_USER = "locked_user";
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.LockIcon";
}
/**
* @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.lockImage = (String)values[1];
this.lockOwnerImage = (String)values[2];
this.align = (String)values[3];
this.width = ((Integer)values[4]).intValue();
this.height = ((Integer)values[5]).intValue();
this.value = values[6];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[7];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.lockImage;
values[2] = this.lockOwnerImage;
values[3] = this.align;
values[4] = this.width;
values[5] = this.height;
values[6] = this.value;
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();
// get the value and see if the image is locked
NodeService nodeService = getNodeService(context);
boolean locked = false;
boolean lockedOwner = false;
Object val = getValue();
NodeRef ref = null;
if (val instanceof NodeRef)
{
ref = (NodeRef)val;
if (nodeService.exists(ref) && nodeService.hasAspect(ref, ContentModel.ASPECT_LOCKABLE) == true)
{
LockStatus lockStatus = getLockService(context).getLockStatus(ref);
locked = (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER);
lockedOwner = (lockStatus == LockStatus.LOCK_OWNER);
}
}
String msg = null;
if (locked == true)
{
out.write("&nbsp;<img");
outputAttribute(out, getAttributes().get("style"), "style");
outputAttribute(out, getAttributes().get("styleClass"), "class");
outputAttribute(out, getAlign(), "align");
outputAttribute(out, getWidth(), "width");
outputAttribute(out, getHeight(), "height");
out.write("src=\"");
out.write(context.getExternalContext().getRequestContextPath());
String lockImage = getLockImage();
if (lockedOwner == true && getLockOwnerImage() != null)
{
lockImage = getLockOwnerImage();
}
out.write(lockImage);
out.write("\" border=0");
if (lockedOwner == true)
{
msg = Application.getMessage(context, MSG_LOCKED_YOU);
if (getLockedOwnerTooltip() != null)
{
msg = getLockedOwnerTooltip();
}
}
else
{
String lockingUser = (String)nodeService.getProperty(ref, ContentModel.PROP_LOCK_OWNER);
msg = Application.getMessage(context, MSG_LOCKED_USER);
if (getLockedUserTooltip() != null)
{
msg = getLockedUserTooltip();
}
StringBuilder buf = new StringBuilder(32);
msg = buf.append(msg).append(" '")
.append(lockingUser)
.append("'").toString();
}
msg = Utils.encode(msg);
out.write(" alt=\"");
out.write(msg);
out.write("\" title=\"");
out.write(msg);
out.write("\">");
}
}
/**
* Use Spring JSF integration to return the Node Service bean instance
*
* @param context FacesContext
*
* @return Node Service bean instance or throws exception if not found
*/
private static NodeService getNodeService(FacesContext context)
{
NodeService service = Repository.getServiceRegistry(context).getNodeService();
if (service == null)
{
throw new IllegalStateException("Unable to obtain NodeService bean reference.");
}
return service;
}
/**
* Use Spring JSF integration to return the Lock Service bean instance
*
* @param context FacesContext
*
* @return Lock Service bean instance or throws exception if not found
*/
private static LockService getLockService(FacesContext context)
{
LockService service = Repository.getServiceRegistry(context).getLockService();
if (service == null)
{
throw new IllegalStateException("Unable to obtain LockService bean reference.");
}
return service;
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* @return the image to display as the lock icon. A default is provided if none is set.
*/
public String getLockImage()
{
ValueBinding vb = getValueBinding("lockImage");
if (vb != null)
{
this.lockImage = (String)vb.getValue(getFacesContext());
}
return this.lockImage;
}
/**
* @param lockImage the image to display as the lock icon. A default is provided if none is set.
*/
public void setLockImage(String lockImage)
{
this.lockImage = lockImage;
}
/**
* @return Returns the image to display if the owner has the lock.
*/
public String getLockOwnerImage()
{
ValueBinding vb = getValueBinding("lockOwnerImage");
if (vb != null)
{
this.lockOwnerImage = (String)vb.getValue(getFacesContext());
}
return this.lockOwnerImage;
}
/**
* @param lockOwnerImage the image to display if the owner has the lock.
*/
public void setLockOwnerImage(String lockOwnerImage)
{
this.lockOwnerImage = lockOwnerImage;
}
/**
* @return Returns the image alignment value.
*/
public String getAlign()
{
ValueBinding vb = getValueBinding("align");
if (vb != null)
{
this.align = (String)vb.getValue(getFacesContext());
}
return this.align;
}
/**
* @param align The image alignment value to set.
*/
public void setAlign(String align)
{
this.align = align;
}
/**
* @return Returns the icon height.
*/
public int getHeight()
{
ValueBinding vb = getValueBinding("height");
if (vb != null)
{
Integer value = (Integer)vb.getValue(getFacesContext());
if (value != null)
{
this.height = value.intValue();
}
}
return this.height;
}
/**
* @param height The icon height to set.
*/
public void setHeight(int height)
{
this.height = height;
}
/**
* @return Returns the icon width.
*/
public int getWidth()
{
ValueBinding vb = getValueBinding("width");
if (vb != null)
{
Integer value = (Integer)vb.getValue(getFacesContext());
if (value != null)
{
this.width = value.intValue();
}
}
return this.width;
}
/**
* @param width The iconwidth to set.
*/
public void setWidth(int width)
{
this.width = width;
}
/**
* @return Returns the lockedOwnerTooltip.
*/
public String getLockedOwnerTooltip()
{
ValueBinding vb = getValueBinding("lockedOwnerTooltip");
if (vb != null)
{
this.lockedOwnerTooltip = (String)vb.getValue(getFacesContext());
}
return this.lockedOwnerTooltip;
}
/**
* @param lockedOwnerTooltip The lockedOwnerTooltip to set.
*/
public void setLockedOwnerTooltip(String lockedOwnerTooltip)
{
this.lockedOwnerTooltip = lockedOwnerTooltip;
}
/**
* @return Returns the lockedUserTooltip.
*/
public String getLockedUserTooltip()
{
ValueBinding vb = getValueBinding("lockedUserTooltip");
if (vb != null)
{
this.lockedUserTooltip = (String)vb.getValue(getFacesContext());
}
return this.lockedUserTooltip;
}
/**
* @param lockedUserTooltip The lockedUserTooltip to set.
*/
public void setLockedUserTooltip(String lockedUserTooltip)
{
this.lockedUserTooltip = lockedUserTooltip;
}
/**
* @return Returns the value (Node or NodeRef)
*/
public Object getValue()
{
ValueBinding vb = getValueBinding("value");
if (vb != null)
{
this.value = vb.getValue(getFacesContext());
}
return this.value;
}
/**
* @param value The Node or NodeRef value to set.
*/
public void setValue(Object value)
{
this.value = value;
}
private String lockImage = WebResources.IMAGE_LOCK;
private String lockOwnerImage = WebResources.IMAGE_LOCK_OWNER;
private String align = null;
private int width = 16;
private int height = 16;
private String lockedOwnerTooltip = null;
private String lockedUserTooltip = null;
private Object value = null;
}

View File

@@ -0,0 +1,361 @@
/*
* 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.repo.component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
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;
import org.alfresco.web.app.Application;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This component wraps a standard component to give it multi value capabilities.
*
* A list of existing values are available, items can be removed from this list
* or new items added to the list. To add new items the component dynamically
* shows the child component this one wraps.
*
* @author gavinc
*/
public class UIMultiValueEditor extends UIInput
{
private static final Log logger = LogFactory.getLog(UIMultiValueEditor.class);
private static final String MSG_SELECTED_ITEMS = "selected_items";
private static final String MSG_NO_SELECTED_ITEMS = "no_selected_items";
private static final String MSG_SELECT_ITEM = "select_an_item";
public final static String ACTION_SEPARATOR = ";";
public final static int ACTION_NONE = -1;
public final static int ACTION_REMOVE = 0;
public final static int ACTION_SELECT = 1;
public final static int ACTION_ADD = 2;
private Boolean addingNewItem = Boolean.FALSE;
private Boolean readOnly;
private Object lastItemAdded;
private String selectItemMsg;
private String selectedItemsMsg;
private String noSelectedItemsMsg;
// ------------------------------------------------------------------------------
// Component implementation
/**
* Default constructor
*/
public UIMultiValueEditor()
{
setRendererType("org.alfresco.faces.List");
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.MultiValueEditor";
}
/**
* @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.lastItemAdded = values[1];
this.readOnly = (Boolean)values[2];
this.addingNewItem = (Boolean)values[3];
this.selectItemMsg = (String)values[4];
this.selectedItemsMsg = (String)values[5];
this.noSelectedItemsMsg = (String)values[6];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[7];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.lastItemAdded;
values[2] = this.readOnly;
values[3] = this.addingNewItem;
values[4] = this.selectItemMsg;
values[5] = this.selectedItemsMsg;
values[6] = this.noSelectedItemsMsg;
return (values);
}
/**
* Returns the last item added by the user
*
* @return The last item added
*/
public Object getLastItemAdded()
{
ValueBinding vb = getValueBinding("lastItemAdded");
if (vb != null)
{
this.lastItemAdded = vb.getValue(getFacesContext());
}
return this.lastItemAdded;
}
/**
* Sets the last item to be added by the user
*
* @param lastItemAdded The last item added
*/
public void setLastItemAdded(Object lastItemAdded)
{
this.lastItemAdded = lastItemAdded;
}
/**
* Returns the message to display for the selected items, if one hasn't been
* set it defaults to the message in the bundle under key 'selected_items'.
*
* @return The message
*/
public String getSelectedItemsMsg()
{
ValueBinding vb = getValueBinding("selectedItemsMsg");
if (vb != null)
{
this.selectedItemsMsg = (String)vb.getValue(getFacesContext());
}
if (this.selectedItemsMsg == null)
{
this.selectedItemsMsg = Application.getMessage(getFacesContext(), MSG_SELECTED_ITEMS);
}
return this.selectedItemsMsg;
}
/**
* Sets the selected items message to display in the UI
*
* @param selectedItemsMsg The message
*/
public void setSelectedItemsMsg(String selectedItemsMsg)
{
this.selectedItemsMsg = selectedItemsMsg;
}
/**
* Returns the message to display when no items have been selected, if one hasn't been
* set it defaults to the message in the bundle under key 'no_selected_items'.
*
* @return The message
*/
public String getNoSelectedItemsMsg()
{
ValueBinding vb = getValueBinding("noSelectedItemsMsg");
if (vb != null)
{
this.noSelectedItemsMsg = (String)vb.getValue(getFacesContext());
}
if (this.noSelectedItemsMsg == null)
{
this.noSelectedItemsMsg = Application.getMessage(getFacesContext(), MSG_NO_SELECTED_ITEMS);
}
return this.noSelectedItemsMsg;
}
/**
* Sets the no selected items message to display in the UI
*
* @param noSelectedItemsMsg The message
*/
public void setNoSelectedItemsMsg(String noSelectedItemsMsg)
{
this.noSelectedItemsMsg = noSelectedItemsMsg;
}
/**
* Returns the message to display for select an item, if one hasn't been
* set it defaults to the message in the bundle under key 'select_an_item'.
*
* @return The message
*/
public String getSelectItemMsg()
{
ValueBinding vb = getValueBinding("selectItemMsg");
if (vb != null)
{
this.selectItemMsg = (String)vb.getValue(getFacesContext());
}
if (this.selectItemMsg == null)
{
this.selectItemMsg = Application.getMessage(getFacesContext(), MSG_SELECT_ITEM);
}
return this.selectItemMsg;
}
/**
* Sets the select an item message to display in the UI
*
* @param selectedItemsMsg The message
*/
public void setSelectItemMsg(String selectItemMsg)
{
this.selectItemMsg = selectItemMsg;
}
/**
* Determines whether the component is in read only mode
*
* @return true if the component is in read only mode
*/
public boolean getReadOnly()
{
ValueBinding vb = getValueBinding("readOnly");
if (vb != null)
{
this.readOnly = (Boolean)vb.getValue(getFacesContext());
}
if (this.readOnly == null)
{
this.readOnly = Boolean.FALSE;
}
return this.readOnly.booleanValue();
}
/**
* Sets the read only mode for the component
*
* @param readOnly true to set read only mode
*/
public void setReadOnly(boolean readOnly)
{
this.readOnly = Boolean.valueOf(readOnly);
}
/**
* Determines whether the component is adding a new item
*
* @return true if we are adding a new item
*/
public boolean getAddingNewItem()
{
return this.addingNewItem.booleanValue();
}
/**
* @see javax.faces.component.UIComponent#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof MultiValueEditorEvent)
{
MultiValueEditorEvent assocEvent = (MultiValueEditorEvent)event;
List items = (List)getValue();
switch (assocEvent.Action)
{
case ACTION_SELECT:
{
this.addingNewItem = Boolean.TRUE;
break;
}
case ACTION_ADD:
{
if (items == null)
{
items = new ArrayList();
setSubmittedValue(items);
}
items.add(getLastItemAdded());
this.addingNewItem = Boolean.FALSE;
// get hold of the value binding for the lastItemAdded property
// and set it to null to show it's been added to the list
ValueBinding vb = getValueBinding("lastItemAdded");
if (vb != null)
{
vb.setValue(FacesContext.getCurrentInstance(), null);
}
break;
}
case ACTION_REMOVE:
{
items.remove(assocEvent.RemoveIndex);
break;
}
}
}
else
{
super.broadcast(event);
}
}
/**
* @see javax.faces.component.UIComponent#getRendersChildren()
*/
public boolean getRendersChildren()
{
// only show the wrapped component when the add button has been clicked
return !this.addingNewItem.booleanValue();
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing an action relevant to the ChildAssociationEditor component.
*/
public static class MultiValueEditorEvent extends ActionEvent
{
public int Action;
public int RemoveIndex;
public MultiValueEditorEvent(UIComponent component, int action, int removeIndex)
{
super(component);
this.Action = action;
this.RemoveIndex = removeIndex;
}
}
}

View File

@@ -0,0 +1,176 @@
/*
* 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.repo.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.ActionEvent;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* @author Kevin Roast
*/
public class UINodeDescendants extends UICommand
{
// ------------------------------------------------------------------------------
// Construction
/**
* Default constructor
*/
public UINodeDescendants()
{
setRendererType("org.alfresco.faces.NodeDescendantsLinkRenderer");
}
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.NodeDescendants";
}
/**
* @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.maxChildren = (Integer)values[1];
this.showEllipses = (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.maxChildren;
values[2] = this.showEllipses;
return (values);
}
// ------------------------------------------------------------------------------
// Strongly typed component property accessors
/**
* @return the maximum number of child descendants to be displayed, default maximum is 3.
*/
public int getMaxChildren()
{
ValueBinding vb = getValueBinding("maxChildren");
if (vb != null)
{
this.maxChildren = (Integer)vb.getValue(getFacesContext());
}
if (this.maxChildren != null)
{
return this.maxChildren.intValue();
}
else
{
// return default
return 3;
}
}
/**
* @param value The maximum allowed before the no more links are shown
*/
public void setMaxChildren(int value)
{
if (value > 0 && value <= 256)
{
this.maxChildren = Integer.valueOf(value);
}
}
/**
* @return whether to show ellipses "..." if more descendants than the maxChildren value are found
*/
public boolean getShowEllipses()
{
ValueBinding vb = getValueBinding("showEllipses");
if (vb != null)
{
this.showEllipses = (Boolean)vb.getValue(getFacesContext());
}
if (this.showEllipses != null)
{
return this.showEllipses.booleanValue();
}
else
{
// return default
return true;
}
}
/**
* @param showLink True to show ellipses "..." if more descendants than maxChildren are found
*/
public void setShowEllipses(boolean showEllipses)
{
this.showEllipses = Boolean.valueOf(showEllipses);
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the clicking of a node descendant element.
*/
public static class NodeSelectedEvent extends ActionEvent
{
public NodeSelectedEvent(UIComponent component, NodeRef nodeRef, boolean isParent)
{
super(component);
this.NodeReference = nodeRef;
this.IsParent = isParent;
}
public NodeRef NodeReference;
public boolean IsParent;
}
// ------------------------------------------------------------------------------
// Private data
/** maximum number of child descendants to display */
private Integer maxChildren = null;
/** whether to show ellipses if more descendants than the maxChildren are found */
private Boolean showEllipses = null;
}

View File

@@ -0,0 +1,70 @@
/*
* 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.repo.component;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.event.ActionEvent;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* @author Kevin Roast
*/
public class UINodePath extends UICommand
{
// ------------------------------------------------------------------------------
// Construction
/**
* Default constructor
*/
public UINodePath()
{
setRendererType("org.alfresco.faces.NodePathLinkRenderer");
}
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.NodePath";
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing the clicking of a part of the path element.
*/
public static class PathElementEvent extends ActionEvent
{
public PathElementEvent(UIComponent component, NodeRef nodeRef)
{
super(component);
this.NodeReference = nodeRef;
}
public NodeRef NodeReference;
}
}

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.repo.component;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIOutput;
import javax.faces.component.UIPanel;
import javax.faces.component.UISelectBoolean;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.config.ConfigService;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.config.ClientConfigElement.CustomProperty;
import org.alfresco.web.ui.common.ComponentConstants;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.SelfRenderingComponent;
import org.alfresco.web.ui.repo.RepoConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.jsf.FacesContextUtils;
/**
* @author Kevin Roast
*/
public class UISearchCustomProperties extends SelfRenderingComponent implements NamingContainer
{
public static final String PREFIX_DATE_TO = "to_";
public static final String PREFIX_DATE_FROM = "from_";
private static final String MSG_TO = "to";
private static final String MSG_FROM = "from";
private static Log logger = LogFactory.getLog(UISearchCustomProperties.class);
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.AdvancedSearch";
}
/**
* @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();
if (getChildCount() == 0)
{
createComponentsFromConfig(context);
}
// encode the components in a 2 column table
out.write("<table cellspacing=2 cellpadding=2 border=0");
outputAttribute(out, getAttributes().get("styleClass"), "class");
outputAttribute(out, getAttributes().get("style"), "style");
out.write('>');
List<UIComponent> children = getChildren();
int colCounter = 0;
for (int i=0; i<children.size(); i++)
{
UIComponent component = children.get(i);
if (component instanceof UIPanel)
{
out.write("<tr><td colspan=2>");
Utils.encodeRecursive(context, component);
out.write("</td></tr>");
colCounter += 2;
}
else
{
if ((colCounter & 1) == 0)
{
out.write("<tr>");
}
out.write("<td>");
Utils.encodeRecursive(context, component);
out.write("</td>");
if ((colCounter & 1) == 1)
{
out.write("</tr>");
}
colCounter++;
}
}
out.write("</table>");
}
/**
* Build the components from the Advanced Search config entries
*
* @param context FacesContext
*/
private void createComponentsFromConfig(FacesContext context)
{
DictionaryService dd = Repository.getServiceRegistry(context).getDictionaryService();
ConfigService configService = Application.getConfigService(context);
ClientConfigElement clientConfig = (ClientConfigElement)configService.getGlobalConfig().getConfigElement(
ClientConfigElement.CONFIG_ELEMENT_ID);
// create an appropriate component for each custom property
// using the DataDictionary to look-up labels and value types
String beanBinding = (String)getAttributes().get("bean") + '.' + (String)getAttributes().get("var");
List<CustomProperty> props = clientConfig.getCustomProperties();
if (props != null)
{
for (CustomProperty property : props)
{
try
{
// try to find the Property definition for the specified Type or Aspect
PropertyDefinition propDef = null;
if (property.Type != null)
{
QName type = Repository.resolveToQName(property.Type);
TypeDefinition typeDef = dd.getType(type);
propDef = typeDef.getProperties().get(Repository.resolveToQName(property.Property));
}
else if (property.Aspect != null)
{
QName aspect = Repository.resolveToQName(property.Aspect);
AspectDefinition aspectDef = dd.getAspect(aspect);
propDef = aspectDef.getProperties().get(Repository.resolveToQName(property.Property));
}
// if we found a def, then we can build components to represent it
if (propDef != null)
{
// TODO: add display label I18N message support to configelement and here
String label = propDef.getTitle() != null ? propDef.getTitle() : propDef.getName().getLocalName();
// special handling for Date and DateTime
DataTypeDefinition dataTypeDef = propDef.getDataType();
if (DataTypeDefinition.DATE.equals(dataTypeDef.getName()) || DataTypeDefinition.DATETIME.equals(dataTypeDef.getName()))
{
getChildren().add( generateControl(context, propDef, label, beanBinding) );
}
else
{
getChildren().add( generateLabel(context, label) );
getChildren().add( generateControl(context, propDef, null, beanBinding) );
}
}
}
catch (DictionaryException ddErr)
{
logger.warn("Error building custom properties for Advanced Search: " + ddErr.getMessage());
}
}
}
}
/**
* Generates a JSF OutputText component/renderer
*
* @param context JSF context
* @param displayLabel The display label text
* @param parent The parent component for the label
*
* @return UIComponent
*/
private UIComponent generateLabel(FacesContext context, String displayLabel)
{
UIOutput label = (UIOutput)context.getApplication().createComponent(ComponentConstants.JAVAX_FACES_OUTPUT);
label.setId(context.getViewRoot().createUniqueId());
label.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
label.setValue(displayLabel + ": ");
return label;
}
/**
* Generates an appropriate control for the given property
*
* @param context JSF context
* @param propDef The definition of the property to create the control for
* @param displayLabel Display label for the component
* @param beanBinding Combined name of the value bound bean and variable used for value binding expression
*
* @return UIComponent
*/
private UIComponent generateControl(FacesContext context, PropertyDefinition propDef, String displayLabel, String beanBinding)
{
UIComponent control = null;
DataTypeDefinition dataTypeDef = propDef.getDataType();
QName typeName = dataTypeDef.getName();
javax.faces.application.Application facesApp = context.getApplication();
// create default value binding to a Map of values with a defined name
ValueBinding vb = facesApp.createValueBinding(
"#{" + beanBinding + "[\"" + propDef.getName().toString() + "\"]}");
// generate the appropriate input field
if (typeName.equals(DataTypeDefinition.BOOLEAN))
{
control = (UISelectBoolean)facesApp.createComponent(ComponentConstants.JAVAX_FACES_SELECT_BOOLEAN);
control.setRendererType(ComponentConstants.JAVAX_FACES_CHECKBOX);
control.setValueBinding("value", vb);
}
else if (typeName.equals(DataTypeDefinition.CATEGORY))
{
control = (UICategorySelector)facesApp.createComponent(RepoConstants.ALFRESCO_FACES_CATEGORY_SELECTOR);
control.setValueBinding("value", vb);
}
else if (typeName.equals(DataTypeDefinition.DATETIME) || typeName.equals(DataTypeDefinition.DATE))
{
Boolean showTime = Boolean.valueOf(typeName.equals(DataTypeDefinition.DATETIME));
// Need to output component for From and To date selectors and labels
// also neeed checkbox for enable/disable state - requires an outer wrapper component
control = (UIPanel)facesApp.createComponent(ComponentConstants.JAVAX_FACES_PANEL);
control.setRendererType(ComponentConstants.JAVAX_FACES_GRID);
control.getAttributes().put("columns", Integer.valueOf(2));
// enabled state checkbox
UIInput checkbox = (UIInput)facesApp.createComponent(ComponentConstants.JAVAX_FACES_SELECT_BOOLEAN);
checkbox.setRendererType(ComponentConstants.JAVAX_FACES_CHECKBOX);
checkbox.setId(context.getViewRoot().createUniqueId());
ValueBinding vbCheckbox = facesApp.createValueBinding(
"#{" + beanBinding + "[\"" + propDef.getName().toString() + "\"]}");
checkbox.setValueBinding("value", vbCheckbox);
control.getChildren().add(checkbox);
// main display label
UIOutput label = (UIOutput)context.getApplication().createComponent(ComponentConstants.JAVAX_FACES_OUTPUT);
label.setId(context.getViewRoot().createUniqueId());
label.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
label.setValue(displayLabel + ":");
control.getChildren().add(label);
// from date label
UIOutput labelFromDate = (UIOutput)context.getApplication().createComponent(ComponentConstants.JAVAX_FACES_OUTPUT);
labelFromDate.setId(context.getViewRoot().createUniqueId());
labelFromDate.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
labelFromDate.setValue(Application.getMessage(context, MSG_FROM));
control.getChildren().add(labelFromDate);
// from date control
UIInput inputFromDate = (UIInput)facesApp.createComponent(ComponentConstants.JAVAX_FACES_INPUT);
inputFromDate.setId(context.getViewRoot().createUniqueId());
inputFromDate.setRendererType(RepoConstants.ALFRESCO_FACES_DATE_PICKER_RENDERER);
inputFromDate.getAttributes().put("startYear", new Integer(1970));
inputFromDate.getAttributes().put("yearCount", new Integer(50));
inputFromDate.getAttributes().put("showTime", showTime);
ValueBinding vbFromDate = facesApp.createValueBinding(
"#{" + beanBinding + "[\"" + PREFIX_DATE_FROM + propDef.getName().toString() + "\"]}");
inputFromDate.setValueBinding("value", vbFromDate);
control.getChildren().add(inputFromDate);
// to date label
UIOutput labelToDate = (UIOutput)context.getApplication().createComponent(ComponentConstants.JAVAX_FACES_OUTPUT);
labelToDate.setId(context.getViewRoot().createUniqueId());
labelToDate.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
labelToDate.setValue(Application.getMessage(context, MSG_TO));
control.getChildren().add(labelToDate);
// to date control
UIInput inputToDate = (UIInput)facesApp.createComponent(ComponentConstants.JAVAX_FACES_INPUT);
inputToDate.setId(context.getViewRoot().createUniqueId());
inputToDate.setRendererType(RepoConstants.ALFRESCO_FACES_DATE_PICKER_RENDERER);
inputToDate.getAttributes().put("startYear", new Integer(1970));
inputToDate.getAttributes().put("yearCount", new Integer(50));
inputToDate.getAttributes().put("showTime", showTime);
ValueBinding vbToDate = facesApp.createValueBinding(
"#{" + beanBinding + "[\"" + PREFIX_DATE_TO + propDef.getName().toString() + "\"]}");
inputToDate.setValueBinding("value", vbToDate);
control.getChildren().add(inputToDate);
}
else if (typeName.equals(DataTypeDefinition.NODE_REF))
{
control = (UISpaceSelector)facesApp.createComponent(RepoConstants.ALFRESCO_FACES_SPACE_SELECTOR);
control.setValueBinding("value", vb);
}
else
{
// any other type is represented as an input text field
control = (UIInput)facesApp.createComponent(ComponentConstants.JAVAX_FACES_INPUT);
control.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
control.getAttributes().put("size", "28");
control.getAttributes().put("maxlength", "1024");
control.setValueBinding("value", vb);
}
// set up the common aspects of the control
control.setId(context.getViewRoot().createUniqueId());
return control;
}
}

View File

@@ -0,0 +1,343 @@
/*
* 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.repo.component;
import java.io.IOException;
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.alfresco.web.app.Application;
import org.alfresco.web.bean.SearchContext;
import org.alfresco.web.ui.common.Utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Kevin Roast
*/
public class UISimpleSearch extends UICommand
{
// ------------------------------------------------------------------------------
// Component implementation
/**
* Default Constructor
*/
public UISimpleSearch()
{
// 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);
}
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.SimpleSearch";
}
/**
* @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.search = (SearchContext)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.search;
return (values);
}
/**
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
String fieldId = Utils.getActionHiddenFieldName(context, this);
String value = (String)requestMap.get(fieldId);
// we are clicked if the hidden field contained our client id
if (value != null)
{
if (value.equals(this.getClientId(context)))
{
String searchText = (String)requestMap.get(getClientId(context));
if (searchText.length() != 0)
{
if (logger.isDebugEnabled())
logger.debug("Search text submitted: " + searchText);
int option = -1;
String optionFieldName = getClientId(context) + NamingContainer.SEPARATOR_CHAR + OPTION_PARAM;
String optionStr = (String)requestMap.get(optionFieldName);
if (optionStr.length() != 0)
{
option = Integer.parseInt(optionStr);
}
if (logger.isDebugEnabled())
logger.debug("Search option submitted: " + option);
// queue event so system can perform a search and update the component
SearchEvent event = new SearchEvent(this, searchText, option);
this.queueEvent(event);
}
}
else if (value.equals(ADVSEARCH_PARAM))
{
// found advanced search navigation action
// TODO: TEMP: set this outcome from a component attribute!
AdvancedSearchEvent event = new AdvancedSearchEvent(this, "advSearch");
this.queueEvent(event);
}
}
}
/**
* @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof SearchEvent)
{
// update the component parameters from the search event details
SearchEvent searchEvent = (SearchEvent)event;
// construct the Search Context object
SearchContext context = new SearchContext();
context.setText(searchEvent.SearchText);
context.setMode(searchEvent.SearchMode);
this.search = context;
super.broadcast(event);
}
else if (event instanceof AdvancedSearchEvent)
{
// special case to navigate to the advanced search screen
AdvancedSearchEvent searchEvent = (AdvancedSearchEvent)event;
FacesContext fc = getFacesContext();
fc.getApplication().getNavigationHandler().handleNavigation(fc, null, searchEvent.Outcome);
// NOTE: we don't call super() here so that our nav outcome is the one that occurs!
}
}
/**
* @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 = (ResourceBundle)Application.getBundle(context);
// script for dynamic simple search menu drop-down options
out.write("<script>");
out.write("function _noenter(event) {" +
"if (event && event.keyCode == 13) {" +
" _searchSubmit();return false; }" +
"else {" +
" return true; } }");
out.write("function _searchSubmit() {");
out.write(Utils.generateFormSubmit(context, this, Utils.getActionHiddenFieldName(context, this), getClientId(context)));
out.write("}");
out.write("</script>");
// outer table containing search drop-down icon, text box and search Go image button
out.write("<table cellspacing=4 cellpadding=0>");
out.write("<tr><td style='padding-top:2px'>");
String searchImage = Utils.buildImageTag(context, "/images/icons/search_icon.gif", 15, 15,
bundle.getString(MSG_GO), "_searchSubmit();");
out.write(Utils.buildImageTag(context, "/images/icons/search_controls.gif", 27, 13,
bundle.getString(MSG_OPTIONS), "javascript:_toggleMenu(event, '_alfsearch');"));
// dynamic DIV area containing search options
out.write("<br><div id='_alfsearch' style='position:absolute;display:none'>");
out.write("<table border=0 bgcolor='#eeeeee' style='border-top:thin solid #FFFFFF;border-left:thin solid #FFFFFF;border-right:thin solid #444444;border-bottom:thin solid #444444;' cellspacing=4 cellpadding=0>");
// output each option - setting the current one to CHECKED
String optionFieldName = getClientId(context) + NamingContainer.SEPARATOR_CHAR + OPTION_PARAM;
String radioOption = "<tr><td class='userInputForm'><input type='radio' name='" + optionFieldName + "'";
out.write(radioOption);
out.write(" VALUE='0'");
int searchMode = getSearchMode();
if (searchMode == 0) out.write(" CHECKED");
out.write("><nobr>" + bundle.getString(MSG_ALL_ITEMS) + "</nobr></td></tr>");
out.write(radioOption);
out.write(" VALUE='1'");
if (searchMode == 1) out.write(" CHECKED");
out.write("><nobr>" + bundle.getString(MSG_FILE_NAMES_CONTENTS) + "</nobr></td></tr>");
out.write(radioOption);
out.write(" VALUE='2'");
if (searchMode == 2) out.write(" CHECKED");
out.write("><nobr>" + bundle.getString(MSG_FILE_NAMES_ONLY) + "</nobr></td></tr>");
out.write(radioOption);
out.write(" VALUE='3'");
if (searchMode == 3) out.write(" CHECKED");
out.write("><nobr>" + bundle.getString(MSG_SPACE_NAMES_ONLY) + "</nobr></td></tr>");
// row with table containing advanced search link and Search Go button
out.write("<tr><td><table width=100%><tr><td>");
// generate a link that will cause an action event to navigate to the advanced search screen
out.write("<a class='small' href='#' onclick=\"");
out.write(Utils.generateFormSubmit(context, this, Utils.getActionHiddenFieldName(context, this), ADVSEARCH_PARAM));
out.write("\">");
out.write(bundle.getString(MSG_ADVANCED_SEARCH));
out.write("</a>");
out.write("</td><td align=right>");
out.write(searchImage);
out.write("</td></tr></table></td></tr>");
out.write("</table></div>");
// input text box
out.write("</td><td>");
out.write("<input name='");
out.write(getClientId(context));
// TODO: style and class from component properties!
out.write("' onkeypress=\"return _noenter(event)\"");
out.write(" type='text' maxlength='1024' style='width:130px;padding-top:3px;font-size:10px' value=\"");
// output previous search text stored in this component!
out.write(Utils.replace(getLastSearch(), "\"", "&quot;"));
out.write("\">");
// search Go image button
out.write("</td><td>");
out.write(searchImage);
// end outer table
out.write("</td></tr></table>");
}
/**
* Return the current Search Context
*/
public SearchContext getSearchContext()
{
return this.search;
}
/**
* @return The last set search text value
*/
public String getLastSearch()
{
if (search != null)
{
return this.search.getText();
}
else
{
return "";
}
}
/**
* @return The current search mode (see constants)
*/
public int getSearchMode()
{
if (search != null)
{
return this.search.getMode();
}
else
{
return SearchContext.SEARCH_ALL;
}
}
// ------------------------------------------------------------------------------
// Private data
private static Log logger = LogFactory.getLog(UISimpleSearch.class);
/** I18N message Ids */
private static final String MSG_ADVANCED_SEARCH = "advanced_search";
private static final String MSG_OPTIONS = "options";
private static final String MSG_GO = "go";
private static final String MSG_SPACE_NAMES_ONLY = "space_names";
private static final String MSG_FILE_NAMES_ONLY = "file_names";
private static final String MSG_FILE_NAMES_CONTENTS = "file_names_contents";
private static final String MSG_ALL_ITEMS = "all_items";
private static final String OPTION_PARAM = "_option";
private static final String ADVSEARCH_PARAM = "_advsearch";
/** last search context used */
private SearchContext search = null;
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class representing a search execution from the UISimpleSearch component.
*/
public static class SearchEvent extends ActionEvent
{
private static final long serialVersionUID = 3918135612344774322L;
public SearchEvent(UIComponent component, String text, int mode)
{
super(component);
SearchText = text;
SearchMode = mode;
}
public String SearchText;
public int SearchMode;
}
public static class AdvancedSearchEvent extends ActionEvent
{
public AdvancedSearchEvent(UIComponent component, String outcome)
{
super(component);
Outcome = outcome;
}
public String Outcome;
}
}

View File

@@ -0,0 +1,131 @@
/*
* 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.repo.component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.repo.WebResources;
/**
* @author Kevin Roast
*/
public class UISpaceSelector extends AbstractItemSelector
{
// ------------------------------------------------------------------------------
// Component Impl
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.SpaceSelector";
}
/**
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getDefaultLabel()
*/
public String getDefaultLabel()
{
return Application.getMessage(FacesContext.getCurrentInstance(), "select_space_prompt");
}
/**
* Returns the parent id of the current space or null if the parent space is the company home space
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getParentNodeId(javax.faces.context.FacesContext)
*/
public String getParentNodeId(FacesContext context)
{
String id = null;
if (this.navigationId != null && this.navigationId.equals(Application.getCompanyRootId()) == false)
{
ChildAssociationRef parentRef = getNodeService(context).getPrimaryParent(
new NodeRef(Repository.getStoreRef(), this.navigationId));
id = parentRef.getParentRef().getId();
}
return id;
}
/**
* Returns the child spaces of the current space
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getChildrenForNode(javax.faces.context.FacesContext)
*/
public Collection<ChildAssociationRef> getChildrenForNode(FacesContext context)
{
NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), this.navigationId);
List<ChildAssociationRef> allKids = getNodeService(context).getChildAssocs(nodeRef);
DictionaryService dd = getDictionaryService(context);
NodeService service = getNodeService(context);
// filter out those children that are not spaces
List<ChildAssociationRef> spaceKids = new ArrayList<ChildAssociationRef>();
for (ChildAssociationRef ref : allKids)
{
if (dd.isSubClass(service.getType(ref.getChildRef()), ContentModel.TYPE_FOLDER) &&
dd.isSubClass(service.getType(ref.getChildRef()), ContentModel.TYPE_SYSTEM_FOLDER) == false)
{
spaceKids.add(ref);
}
}
return spaceKids;
}
/**
* Returns the current users home space
*
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getRootChildren(javax.faces.context.FacesContext)
*/
public Collection<ChildAssociationRef> getRootChildren(FacesContext context)
{
// get the root space from the current user
//String rootId = Application.getCurrentUser(context).getHomeSpaceId();
NodeRef rootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
// get a child association reference back to the real repository root to satisfy
// the generic API we have in the abstract super class
ChildAssociationRef childRefFromRealRoot = getNodeService(context).getPrimaryParent(rootRef);
List<ChildAssociationRef> roots = new ArrayList<ChildAssociationRef>(1);
roots.add(childRefFromRealRoot);
return roots;
}
/**
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getItemIcon()
*/
public String getItemIcon()
{
return WebResources.IMAGE_SPACE;
}
}

Some files were not shown because too many files have changed in this diff Show More