01-22-2008 03:12 PM
<type name="gc:RFC">
<property name="gc:person">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
…
——————————————
| | Id: _______________ |
| | |
| Person: | First Name: _______________ |
| | |
| | Last Name: _______________ |
——————————————
<type name="gc:RFC">
<property name="gc:personID">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="gc:personFirstName">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
<property name="gc:personLastName">
<type>d:text</type>
<mandatory>true</mandatory>
</property>
…
—————————————
| Person Id: _______________ |
| |
| Person First Name: _______________ |
| |
| Person Last Name: _______________ |
—————————————
01-22-2008 03:17 PM
package co.com.arkimia.alfresco.web.bean.generator;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.generator.TextFieldGenerator;
import org.alfresco.web.ui.common.ComponentConstants;
import org.alfresco.web.ui.repo.RepoConstants;
import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
import org.alfresco.web.ui.repo.component.property.UIPropertySheet;
/**
* Multiple fields generator for a single field in model; users can define
* components with its own label, component type, and renderer type.
* Defaults for componentType, renderType and label are javax.faces.Input,
* javax.faces.Text and "" respectively.
* This component supports verticar or horizontal layout.
* @author Juan David Zuluaga Arboleda. Arkimia S.A.
*
*/
public class MultipleFieldsGenerator extends TextFieldGenerator {
public static final String DEFAULT_LABEL = "";
public static final String DEFAULT_COMPONENT_TYPE = ComponentConstants.JAVAX_FACES_INPUT;
public static final String DEFAULT_RENDER_TYPE = ComponentConstants.JAVAX_FACES_TEXT;
private boolean verticalLayout = true;
private List<String> labels;
private List<String> componentTypes;
private List<String> renderTypes;
/**
* Returns the number of fields to be renderer
* @return
*/
private int getNumberOfComponents() {
int components = 0;
if(labels != null) {
components = Math.max(components, labels.size());
}
if(componentTypes != null) {
components = Math.max(components, componentTypes.size());
}
if(renderTypes!= null) {
components = Math.max(components, renderTypes.size());
}
return components;
}
/**
* Returns the grid number of columns, depending of layout type and number
* of components.
* @return
*/
private int getColumns() {
if(verticalLayout) {
return 2;
}
return getNumberOfComponents() * 2;
}
public List<String> getLabels() {
return labels;
}
public void setLabels(List<String> labels) {
this.labels = labels;
}
public List<String> getComponentTypes() {
return componentTypes;
}
public void setComponentTypes(List<String> componentTypes) {
this.componentTypes = componentTypes;
}
public List<String> getRenderTypes() {
return renderTypes;
}
public void setRenderTypes(List<String> renderTypes) {
this.renderTypes = renderTypes;
}
public boolean isVerticalLayout() {
return verticalLayout;
}
public void setVerticalLayout(boolean verticalLayout) {
this.verticalLayout = verticalLayout;
}
/**
* Returns the label of the pos component.
* @param pos the label position
* @return the label, or empty string if not label defined for position.
*/
private String getLabel(int pos) {
return labels == null || labels.size() - 1 < pos
? DEFAULT_LABEL: labels.get(pos);
}
/**
* Returns the component Type of the pos component.
* @param pos the component Type position
* @return the component Type, or javax.faces.Input if not component Type defined
* for position.
*/
private String getComponentType(int pos) {
return componentTypes == null || componentTypes.size() - 1 < pos
? DEFAULT_COMPONENT_TYPE: componentTypes.get(pos);
}
/**
* Returns the render type of the pos component.
* @param pos the render type position
* @return the render type, or javax.faces.Text if not render type defined for
* position.
*/
private String getRenderType(int pos) {
return renderTypes == null || renderTypes.size() - 1 < pos
? DEFAULT_RENDER_TYPE: renderTypes.get(pos);
}
@Override
public UIComponent generate(FacesContext context, String id) {
UIComponent input;
UIOutput output;
UIComponent panel = context.getApplication().createComponent(
"javax.faces.HtmlPanelGrid");
panel.getAttributes().put("columns", getColumns());
panel.setRendererType(ComponentConstants.JAVAX_FACES_GRID);
int numberOfComponents = getNumberOfComponents();
for (int i = 0; i < numberOfComponents; i++) {
output = (UIOutput)context.getApplication().createComponent(
ComponentConstants.JAVAX_FACES_OUTPUT);
output.setValue(getLabel(i));
input = context.getApplication().createComponent(
getComponentType(i));
input.setRendererType(getRenderType(i));
FacesHelper.setupComponentId(context, input, id + "_" + i);
panel.getChildren().add(output);
panel.getChildren().add(input);
}
return panel;
}
@Override
protected UIComponent setupMultiValuePropertyIfNecessary(
FacesContext context, UIPropertySheet propertySheet,
PropertySheetItem property, PropertyDefinition propertyDef,
UIComponent component) {
UIComponent multiValueComponent = component;
if (propertySheet.inEditMode() &&
propertyDef != null && propertyDef.isProtected() == false &&
propertyDef.isMultiValued())
{
// if the property is multi-valued create a multi value editor wrapper component
String id = "multi_" + property.getName();
multiValueComponent = context.getApplication().createComponent(
"co.com.arkimia.alfresco.faces.MultiValueEditor");
multiValueComponent.getAttributes().put("disabled", Boolean.valueOf(property.isReadOnly()));
FacesHelper.setupComponentId(context, multiValueComponent, id);
// set the renderer depending on whether the item is a 'field' or a 'selector'
if (getControlType() == ControlType.FIELD)
{
multiValueComponent.setRendererType(RepoConstants.ALFRESCO_FACES_FIELD_RENDERER);
}
else
{
multiValueComponent.setRendererType(RepoConstants.ALFRESCO_FACES_SELECTOR_RENDERER);
// set the value binding for the wrapped component and the lastItemAdded attribute of
// the multi select component, needs to point somewhere that can hold any object, it
// will store the item last added by the user.
String expr = "#{MultiValueEditorBean.lastItemsAdded['" +
property.getName() + "']}";
ValueBinding vb = context.getApplication().createValueBinding(expr);
multiValueComponent.setValueBinding("lastItemAdded", vb);
component.setValueBinding("value", vb);
}
// add the original component as a child of the wrapper
multiValueComponent.getChildren().add(component);
}
return multiValueComponent;
}
/**
* Removes all component childrens if component is read only.
*/
protected void setupProperty(FacesContext context,
UIPropertySheet propertySheet, PropertySheetItem item,
PropertyDefinition propertyDef, UIComponent component) {
super.setupProperty(context, propertySheet, item, propertyDef,
component);
if (item.isReadOnly()) {
UIComponent panel = (UIComponent) component.getChildren().get(0);
panel.getChildren().removeAll(panel.getChildren());
}
}
}
package co.com.arkimia.alfresco.web.ui.repo.component;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIPanel;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.render.Renderer;
import org.alfresco.web.ui.repo.RepoConstants;
import org.alfresco.web.ui.repo.component.UIMultiValueEditor;
/**
* Takes the information sent in the multiple fields and joins that info in a
* single string
* @author Juan David Zuluaga Arboleda. Arkimia S.A.
*
*/
public class UIMultipleFieldsMultiValueEditor extends UIMultiValueEditor {
public static final String ITEM_SEPARATOR = "°";
public UIMultipleFieldsMultiValueEditor() {
super();
}
@Override
public String getFamily() {
return "co.com.arkimia.alfresco.faces.MultiValueEditor";
}
/**
* Toma los valores de los inputs que existen en el panel hijo de este
* componente.
*/
public void broadcast(FacesEvent event) throws AbortProcessingException {
if (event instanceof MultiValueEditorEvent) {
MultiValueEditorEvent assocEvent = (MultiValueEditorEvent) event;
if(assocEvent.Action == ACTION_ADD) {
List items = (List) getValue();
if (items == null) {
items = new ArrayList();
setSubmittedValue(items);
}
StringBuffer addedItem = new StringBuffer();
if (getRendererType().equals(
(RepoConstants.ALFRESCO_FACES_FIELD_RENDERER))) {
FacesContext context = FacesContext.getCurrentInstance();
UIInput input;
UIComponent component;
UIPanel panel = (UIPanel) this.getChildren().get(0);
for (Iterator iterator = panel.getChildren().iterator();
iterator.hasNext();) {
component = (UIComponent)iterator.next();
if(component instanceof UIInput) {
input = (UIInput) component;
if(input.getSubmittedValue() != null){
Renderer r = context.getRenderKit().getRenderer(
component.getFamily(),
component.getRendererType());
Object value = r.getConvertedValue(context,
component, input.getSubmittedValue());
Converter c = context.getApplication()
.createConverter(value.getClass());
String localValue;
if (c != null) {
localValue = c.getAsString(context,
component, value);
} else {
localValue = value.toString();
}
addedItem.append(localValue);
}
if(iterator.hasNext()){
addedItem.append(ITEM_SEPARATOR);
}
input.setSubmittedValue(null);
}
}
items.add(addedItem.toString());
return;
}
}
}
super.broadcast(event);
}
}
package co.com.arkimia.alfresco.web.ui.repo.renderer;
import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIOutput;
import javax.faces.component.UIPanel;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.app.Application;
import org.alfresco.web.ui.repo.component.UIMultiValueEditor;
import co.com.arkimia.alfresco.web.ui.repo.component.UIMultipleFieldsMultiValueEditor;
/**
* Renders the multiple fields component.
* @author Juan David Zuluaga Arboleda. Arkimia S.A.
*/
public class MultipleFieldsMultiValueRenderer extends PatchedMultiValueFieldRenderer {
/**
* Tokeniza el valor y muestra una columna por cada token del valor.
*/
protected void renderExistingItem(FacesContext context,
UIComponent component, ResponseWriter out, NodeService nodeService,
int index, Object value) throws IOException {
out.write("<tr>");
StringTokenizer newValue = new StringTokenizer((String) value,
UIMultipleFieldsMultiValueEditor.ITEM_SEPARATOR, true);
int tokens = newValue.countTokens();
String nextToken;
out.write("<td class='selectedItemsRow");
if (this.highlightedRow) {
out.write("Alt");
}
out.write("'>");
for (int i = 0; i < tokens; i++) {
nextToken = newValue.nextToken();
if(nextToken.equals(UIMultipleFieldsMultiValueEditor.ITEM_SEPARATOR)) {
out.write(" </td>");
out.write("<td class='selectedItemsRow");
if (this.highlightedRow) {
out.write("Alt");
}
out.write("'>");
} else {
out.write(nextToken);
}
}
out.write(" </td>");
Boolean disabled = (Boolean)component.getAttributes().get("disabled");
if(disabled == null || disabled.equals(Boolean.FALSE)){
out.write("<td class='selectedItemsRow");
if (super.highlightedRow) {
out.write("Alt");
}
out.write("'><a href='#' title='");
out.write(Application.getMessage(context, MSG_REMOVE));
out.write("' onclick=\"");
out.write(generateFormSubmit(context, component,
UIMultiValueEditor.ACTION_REMOVE + UIMultiValueEditor.ACTION_SEPARATOR + index));
out.write("\"><img src='");
out.write(context.getExternalContext().getRequestContextPath());
out.write("/images/icons/delete.gif' border='0' width='13' height='16'/></a>");
}
this.highlightedRow = !this.highlightedRow;
}
/**
* if component disabled does not render delete action
*/
protected void renderPostWrappedComponent(FacesContext context,
ResponseWriter out, UIMultiValueEditor editor) throws IOException {
Boolean disabled = (Boolean) editor.getAttributes().get("disabled");
if (disabled != null && disabled.equals(Boolean.TRUE)) {
out.write("</td></tr>");
} else {
super.renderPostWrappedComponent(context, out, editor);
}
}
protected void renderTableHeader(FacesContext context,
UIComponent component,ResponseWriter out) throws IOException{
UIPanel panel = (UIPanel) component.getChildren().get(0);
Object tmpComp;
UIOutput campo;
out.write("<tr>");
for (Iterator iterator = panel.getChildren().iterator(); iterator.hasNext();) {
tmpComp = iterator.next();
if (!(tmpComp instanceof UIInput)) {
campo = (UIOutput) tmpComp;
out.write("<td class='selectedItemsHeader'>");
out.write(campo.getValue().toString());
out.write("</td>");
}
}
out.write("<td></td>");
out.write("</tr>");
}
}
package co.com.arkimia.alfresco.web.ui.repo.renderer;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.convert.Converter;
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.component.UIMultiValueEditor;
import org.alfresco.web.ui.repo.renderer.MultiValueFieldRenderer;
/**
* Allows table header rendering to be dynamic and uses converters to convert an objet to
* String.
*/
public class PatchedMultiValueFieldRenderer extends MultiValueFieldRenderer {
/**
* @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;
}
if (component instanceof UIMultiValueEditor) {
ResponseWriter out = context.getResponseWriter();
UIMultiValueEditor editor = (UIMultiValueEditor) component;
// get hold of the node service
NodeService nodeService = Repository.getServiceRegistry(context)
.getNodeService();
// render the area between the component and current items list
renderPostWrappedComponent(context, out, editor);
// show the currently selected items
out.write("<tr><td style='padding-top:8px'>");
out.write(editor.getSelectedItemsMsg());
out.write("</td></tr>");
out.write("<tr><td><table cellspacing='0' cellpadding='2' border='0' class='selectedItems'>");
renderTableHeader(context, component, out);
List currentItems = (List) editor.getValue();
if (currentItems != null && currentItems.size() > 0) {
for (int x = 0; x < currentItems.size(); x++) {
Object obj = currentItems.get(x);
if (obj != null) {
if (obj instanceof NodeRef) {
if (nodeService.exists((NodeRef) obj)) {
renderExistingItem(context, component, out,
nodeService, x, obj);
} else {
// remove invalid NodeRefs from the list
currentItems.remove(x);
}
} else {
renderExistingItem(context, component, out,
nodeService, x, obj);
}
}
}
} else {
out.write("<tr><td class='selectedItemsRow'>");
out.write(editor.getNoSelectedItemsMsg());
out.write("</td></tr>");
}
// close tables
out.write("</table></td></tr></table>\n");
// output a hidden field containing the current value
out.write("<input type='hidden' id='");
out.write(component.getClientId(context));
out.write("_current_value");
out.write("' name='");
out.write(component.getClientId(context));
out.write("_current_value");
out.write("' value='");
if (currentItems != null && currentItems.size() > 0) {
out.write(currentItems.toString());
}
out.write("' />");
}
}
protected void renderTableHeader(FacesContext context,
UIComponent component,ResponseWriter out) throws IOException{
out.write("<tr><td colspan='2' class='selectedItemsHeader'>");
out.write(Application.getMessage(context, "name"));
out.write("</td></tr>");
}
protected void renderExistingItem(FacesContext context,
UIComponent component, ResponseWriter out, NodeService nodeService,
int index, Object value) throws IOException {
if (value instanceof NodeRef || value instanceof Date
|| value instanceof Boolean) {
super.renderExistingItem(context, component, out, nodeService,
index, value);
} else {
String localValue = getStringValue(context, component, value);
super.renderExistingItem(context, component, out, nodeService,
index, localValue);
}
}
protected String getStringValue(FacesContext context, UIComponent component, Object value) {
Converter converter = context.getApplication().createConverter(
value.getClass());
String localValue;
if (converter != null) {
localValue = converter.getAsString(context, component, value);
} else {
localValue = value.toString();
}
return localValue;
}
}
…
<managed-bean>
<description>
Bean that generates inputs for a Person
</description>
<managed-bean-name>PersonGenerator</managed-bean-name>
<managed-bean-class>
co.com.arkimia.alfresco.web.bean.generator.MultipleFieldsGenerator
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>componentTypes</property-name>
<list-entries>
<value>javax.faces.Input</value>
<value>javax.faces.Input</value>
<value>javax.faces.Input</value>
<value>javax.faces.Input</value>
</list-entries>
</managed-property>
<managed-property>
<property-name>renderTypes</property-name>
<list-entries>
<value>javax.faces.Text</value>
<value>javax.faces.Text</value>
<value>javax.faces.Text</value>
<value>javax.faces.Textarea</value>
</list-entries>
</managed-property>
<managed-property>
<property-name>labels</property-name>
<list-entries>
<value>Id</value>
<value>First Name</value>
<value>Last Name</value>
<value>Recomendation</value>
</list-entries>
</managed-property>
</managed-bean>
<managed-bean>
<description>
Bean that generates inputs for a Department
</description>
<managed-bean-name>DepartmentGenerator</managed-bean-name>
<managed-bean-class>
co.com.arkimia.alfresco.web.bean.generator.MultipleFieldsGenerator
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>componentTypes</property-name>
<list-entries>
<value>javax.faces.Input</value>
<value>javax.faces.Input</value>
<value>javax.faces.SelectBoolean</value>
</list-entries>
</managed-property>
<managed-property>
<property-name>renderTypes</property-name>
<list-entries>
<value>javax.faces.Text</value>
<value>javax.faces.Text</value>
<value>javax.faces.Checkbox</value>
</list-entries>
</managed-property>
<managed-property>
<property-name>labels</property-name>
<list-entries>
<value>Id</value>
<value>Name</value>
<value>Enabled</value>
</list-entries>
</managed-property>
</managed-bean>
…
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.