static { // Note: Java Package versioning is useless during development when // we have no JARs, whereas this technique works with non-JAR // classpaths as well. String version = "unknown"; try { URL resource = ClassLoaderUtils.getResource("META-INF/trinidad-version.txt"); if (resource != null) { BufferedReader br = null; try { InputStream in = resource.openStream(); br = new BufferedReader(new InputStreamReader(in)); version = br.readLine(); } catch (IOException e) { _LOG.severe(e); } finally { if (br != null) br.close(); } } } catch (IOException e) { _LOG.severe(e); } finally { _VERSION = version; } }
/** * The implementation of agent interface * * <p>This implementation supports agents recognized by all uix22 This class returns name strings * (instead of int's) Certain agents/platforms have been renamed - using "webkit" (instead of * safari), on recommendation from uix team - using "gecko" for all gecko based browsers - using * "ppc" (instead of windows) for platform * * <p> */ public class AgentImpl extends DefaultAgent { public AgentImpl() { this(false); } public AgentImpl(boolean nullAgentEntry) { if (nullAgentEntry) { _LOG.warning("UNKNOWN_AGENT_TYPE_CREATE_WITH_NULL"); _entry = _NULL_AGENT_ENTRY; } else { _entry = new AgentEntry(); } } /* public AgentImpl(String userAgent, String accept) { _entry = _getAgentEntry(userAgent, accept); } */ @Override public Object getType() { return _entry._type; } @Override public String getAgentName() { return _entry._agent; } @Override public String getAgentVersion() { return _entry._agentVersion; } @Override public String getPlatformName() { return _entry._platform; } @Override public String getPlatformVersion() { return _entry._platformVersion; } @Override public String getHardwareMakeModel() { return _entry._makeModel; } @Override public Map<Object, Object> getCapabilities() { return _requestCapabilities; } // setter methods for AgentImpl public void setType(Object type) { _entry._type = type; } public void setAgent(String agent) { _entry._agent = agent; } public void setAgentVersion(String version) { _entry._agentVersion = version; } public void setPlatform(String platform) { _entry._platform = platform; } public void setPlatformVersion(String version) { _entry._platformVersion = version; } public void setMakeModel(String makemodel) { _entry._makeModel = makemodel; } public void setAgentEntryToNULL() { _entry = _NULL_AGENT_ENTRY; } // Private entry structure to // store the Agent attributes private static class AgentEntry { Object _type = TYPE_UNKNOWN; String _agent; String _agentVersion; String _platform; String _platformVersion; String _makeModel; } void __addRequestCapability(CapabilityKey key, Object value) { if (_requestCapabilities == null) { _requestCapabilities = new HashMap<Object, Object>(); } _requestCapabilities.put(key, value); } private HashMap<Object, Object> _requestCapabilities; private AgentEntry _entry; private static final AgentEntry _NULL_AGENT_ENTRY = new AgentEntry(); private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(AgentImpl.class); }
public class ConfigParser { /** */ public static RequestContextBean parseConfigFile(ExternalContext externalContext) { RequestContextBean bean = new RequestContextBean(); InputStream in = externalContext.getResourceAsStream(_CONFIG_FILE); if (in != null) { try { InputSource input = new InputSource(); input.setByteStream(in); input.setPublicId(_CONFIG_FILE); XMLReader reader = _SAX_PARSER_FACTORY.newSAXParser().getXMLReader(); reader.setContentHandler(new Handler(bean, externalContext)); reader.parse(input); } catch (IOException ioe) { _LOG.warning(ioe); } catch (ParserConfigurationException pce) { _LOG.warning(pce); } catch (SAXException saxe) { _LOG.warning(saxe); } finally { try { in.close(); } catch (IOException ioe) { // Ignore ; } } } String classNameString = (String) bean.getProperty(RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY); if (classNameString != null) { classNameString = classNameString.trim(); // check if this contains multiple class names for chained processors usecase. // Usually the class named are separated by space char. String classNames[] = classNameString.split("[ ]+"); if (classNames.length == 1) { // This could be a single processor full override usecase or a chained // processor usecase that has only one processor. try { Class<UploadedFileProcessor> clazz = (Class<UploadedFileProcessor>) ClassLoaderUtils.loadClass(classNames[0]); if (ChainedUploadedFileProcessor.class.isAssignableFrom(clazz)) { // this single chained processor case ChainedUploadedFileProcessor cufp[] = { (ChainedUploadedFileProcessor) clazz.newInstance() }; bean.setProperty( RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY, new CompositeUploadedFileProcessorImpl(Arrays.asList(cufp))); } else { // this is full override usecase bean.setProperty(RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY, clazz.newInstance()); } } catch (Exception e) { _LOG.severe("CANNOT_INSTANTIATE_UPLOADEDFILEPROCESSOR", e); bean.setProperty( RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY, new CompositeUploadedFileProcessorImpl()); } } else { try { // chained processors usecase, Multiple processors List<ChainedUploadedFileProcessor> processors = new ArrayList<ChainedUploadedFileProcessor>(classNames.length); for (String className : classNames) { Class<ChainedUploadedFileProcessor> clazz = (Class<ChainedUploadedFileProcessor>) ClassLoaderUtils.loadClass(className); processors.add(clazz.newInstance()); } bean.setProperty( RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY, new CompositeUploadedFileProcessorImpl(processors)); } catch (Exception e) { _LOG.severe("CANNOT_INSTANTIATE_UPLOADEDFILEPROCESSOR", e); bean.setProperty( RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY, new CompositeUploadedFileProcessorImpl()); } } } else { // nothing specified, hence use default. bean.setProperty( RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY, new CompositeUploadedFileProcessorImpl()); } UploadedFileProcessor ufp = (UploadedFileProcessor) bean.getProperty(RequestContextBean.UPLOADED_FILE_PROCESSOR_KEY); ufp.init(externalContext.getContext()); if (_LOG.isInfo()) { Object debug = bean.getProperty(RequestContextBean.DEBUG_OUTPUT_KEY); if (Boolean.TRUE.equals(debug)) _LOG.info("RUNNING_IN_DEBUG_MODE", _CONFIG_FILE); } return bean; } private static class Handler extends DefaultHandler { @SuppressWarnings("unchecked") public Handler(RequestContextBean bean, ExternalContext context) { _applicationMap = context.getApplicationMap(); _bean = bean; } @Override public void startElement(String uri, String localName, String qName, Attributes atts) { _currentText = ""; } @Override public void characters(char[] ch, int start, int length) { if (_currentText != null) _currentText = _currentText + new String(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) { String currentText = _currentText; if (currentText == null) return; currentText = currentText.trim(); if (!"".equals(currentText)) { PropertyKey key = _bean.getType().findKey(localName); if (key == null) { if (_LOG.isWarning()) _LOG.warning("ELEMENT_NOT_UNDERSTOOD", qName); } else { if (currentText.startsWith("#{") && currentText.endsWith("}")) { if (!key.getSupportsBinding()) { if (_LOG.isWarning()) _LOG.warning("NOT_SUPPORT_EL_EXPRESSION", qName); } else { ValueExpression expression = LazyValueExpression.createValueExpression(_currentText, key.getType()); _bean.setValueExpression(key, expression); } } else { Object value; if (key.getType() == Character.class) { value = currentText.charAt(0); } else if (key.getType() == Integer.class) { value = _getIntegerValue(currentText, qName); } else if (key.getType() == Long.class) { value = _getLongValue(currentText, qName); } else if (key.getType() == Boolean.class) { value = ("true".equalsIgnoreCase(currentText) ? Boolean.TRUE : Boolean.FALSE); } else if (key.getType() == TimeZone.class) { value = DateUtils.getSupportedTimeZone(currentText); if (value == null) { _LOG.warning("INVALID_TIMEZONE_IN_CONFIG", currentText); } } else if (key.getType() == Locale.class) { currentText = currentText.replace('_', '-'); value = LocaleUtils.getLocaleForIANAString(currentText); } else if (key.getType().isEnum()) { // TODO: warn when value is not OK try { value = Enum.valueOf((Class<? extends Enum>) key.getType(), currentText); } catch (IllegalArgumentException iae) { _LOG.warning("INVALID_ENUM_IN_CONFIG", new Object[] {currentText, qName}); return; } } else if (key.getType() == AccessibilityProfile.class) { value = _getAccessibilityProfile(currentText); } else { value = currentText; } if (key == RequestContextBean.REMOTE_DEVICE_REPOSITORY_URI) { _applicationMap.put("remote-device-repository-uri", value); } else if (key == RequestContextBean.CLIENT_VALIDATION_DISABLED_KEY) { if (Boolean.TRUE.equals(value)) _bean.setProperty( RequestContextBean.CLIENT_VALIDATION_KEY, RequestContext.ClientValidation.DISABLED); } else { _bean.setProperty(key, value); } } } } _currentText = null; } private static Integer _getIntegerValue(String text, String qName) { Integer value = null; try { value = Integer.valueOf(text); } catch (NumberFormatException nfe) { if (_LOG.isWarning()) { _LOG.warning("ELEMENT_ONLY_ACCEPT_INTEGER", qName); } } return value; } private static Long _getLongValue(String text, String qName) { Long value = null; try { value = Long.valueOf(text); } catch (NumberFormatException nfe) { if (_LOG.isWarning()) { _LOG.warning("ELEMENT_ONLY_ACCEPT_LONG", qName); } } return value; } // Parses the text into an AccessibilityProfile. private static AccessibilityProfile _getAccessibilityProfile(String text) { AccessibilityProfile.ColorContrast colorContrast = null; AccessibilityProfile.FontSize fontSize = null; // Note: we do the parsing here in the ConfigParser instead of in // RequestContextImpl so that we can easily detect/log any problems // once at startup. Also nice to do this here so that we have some // chance of actually logging line numbers, though at the moment it // looks like our Handler doesn't implement Locator. StringTokenizer tokens = new StringTokenizer(text); while (tokens.hasMoreTokens()) { String token = tokens.nextToken(); if ("high-contrast".equals(token)) { colorContrast = AccessibilityProfile.ColorContrast.HIGH; } else if ("large-fonts".equals(token)) { fontSize = AccessibilityProfile.FontSize.LARGE; } else { _LOG.warning("INVALID_ACC_PROFILE", new Object[] {token}); } } return AccessibilityProfile.getInstance(colorContrast, fontSize); } private RequestContextBean _bean; private String _currentText; private Map<String, Object> _applicationMap; } private static final SAXParserFactory _SAX_PARSER_FACTORY; static { _SAX_PARSER_FACTORY = SAXParserFactory.newInstance(); _SAX_PARSER_FACTORY.setNamespaceAware(true); } private static final String _CONFIG_FILE = "/WEB-INF/trinidad-config.xml"; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ConfigParser.class); }
/** * Renderer for PanelRadio * * @version $Name: $ ($Revision$) $Date$ */ public class CorePanelRadioRenderer extends ShowOneListRendererBase { /** {@inheritDoc} */ @Override protected void renderListDisplay( FacesContext context, UIComponent component, String disclosedChildId) throws IOException { _LOG.finest("CorePanelRadioRenderer.renderRadioFacet: disclosedChildId: {0}", disclosedChildId); // This renders the select controls alongwith javascript onchange handler. UIXRenderingContext rCtx = getRenderingContext(context, component); String compId = component.getClientId(context); ResponseWriter out = context.getResponseWriter(); // draw table to contain the select UI control out.startElement("table", component); out.writeAttribute("id", compId + _RADIO_TABLE_SUFFIX_ID_CONST, null); out.writeAttribute("border", "0", null); out.writeAttribute("cellspacing", "0", null); out.writeAttribute("cellpadding", "0", null); if (!XhtmlLafRenderer.isInaccessibleMode(rCtx)) { out.writeAttribute("summary", "", null); } out.startElement("tr", component); String label = (String) component.getAttributes().get("label"); out.startElement("td", component); out.writeAttribute("align", "left", null); out.writeAttribute("nowrap", Boolean.TRUE, null); out.startElement("span", component); XhtmlLafRenderer.renderStyleClassAttribute(rCtx, SkinSelectors.AF_LABEL_TEXT_STYLE_CLASS); if (label != null) out.writeText(label, null); out.endElement("span"); out.endElement("td"); // Render filler / separator between label and select control renderSpacerTD(out, component, getLabelControlSeparatorSize()); _renderRadioItemsInTD(context, component, out, rCtx, compId, disclosedChildId); out.endElement("tr"); out.endElement("table"); } /** * Generates markup for rendering HTML radio controls. * * <p>Each radio control is corresponding to a rendered UIXShowDetail child. The disable * showDetail children are shown as disabled radio buttons. */ @SuppressWarnings("unchecked") private void _renderRadioItemsInTD( FacesContext context, UIComponent component, ResponseWriter out, UIXRenderingContext rCtx, String compId, String disclosedChildId) throws IOException { out.startElement("td", component); out.writeAttribute("valign", "top", null); out.writeAttribute("nowrap", Boolean.TRUE, null); String formName = RenderUtils.getFormId(context, component); // each of the radio buttons would occupy a td in a tr // so there will be as many rows as the number of children and each row // in turn will have only one td - to contain the radio button out.startElement("table", component); out.writeAttribute("id", compId + disclosedChildId, null); out.writeAttribute("summary", "", null); out.writeAttribute("border", "0", null); out.writeAttribute("cellspacing", "0", null); out.writeAttribute("cellpadding", "0", null); ListIterator<UIComponent> children = component.getChildren().listIterator(); while (children.hasNext()) { UIComponent child = children.next(); if (!(child instanceof UIXShowDetail)) { continue; // Can't do any thing with non-showDetail children. } UIXShowDetail detailItem = (UIXShowDetail) child; String childClientId = child.getClientId(context); out.startElement("tr", component); out.startElement("td", component); boolean isRTL = BaseLafUtils.isRightToLeft(rCtx); if (isRTL) { out.writeAttribute("align", "right", null); } else { out.writeAttribute("align", "left", null); } out.writeAttribute("valign", "top", null); out.writeAttribute("nowrap", Boolean.TRUE, null); out.startElement("span", component); out.writeAttribute("id", childClientId + _RADIO_SPAN_SUFFIX_ID_CONST, null); Boolean disabledObj = (Boolean) detailItem.getAttributes().get(UIConstants.DISABLED_ATTR.getAttributeName()); boolean disabled = false; // by default is enabled. if (disabledObj != null) { disabled = disabledObj.booleanValue(); } if (!disclosedChildId.equals(childClientId) && (!disabled)) { boolean isImmediate = detailItem.isImmediate(); String submitJS = _getRadioSubmitJS(component, rCtx, formName, compId, childClientId, isImmediate); // PH:onclick javascript handler for a HTML SPAN element is not supported // on PIE, IE Mobile or Blackberry 4.0. Therefore, create onclick // javascript for non-PDAs only. if (!CoreRenderer.isPDA(RenderingContext.getCurrentInstance())) out.writeAttribute("onclick", submitJS, null); } // render the radio button now out.startElement("input", component); out.writeAttribute("id", childClientId, null); out.writeAttribute("value", childClientId, null); out.writeAttribute("name", compId, null); // PH: onclick javascript handler for an INPUT element is supported on a // PDA. Therefore, create javascript for onclick on an INPUT element // instead of a SPAN element. if (CoreRenderer.isPDA(RenderingContext.getCurrentInstance())) { boolean isImmediate = detailItem.isImmediate(); String submitJS = _getRadioSubmitJS(component, rCtx, formName, compId, childClientId, isImmediate); out.writeAttribute("onclick", submitJS, null); } if (disabled) { out.writeAttribute("disabled", Boolean.TRUE, null); } out.writeAttribute("type", "radio", null); if (disclosedChildId.equals(childClientId)) { out.writeAttribute("checked", Boolean.TRUE, null); } out.endElement("input"); out.startElement("label", component); out.writeAttribute("for", childClientId, null); Character accessChar = (Character) detailItem.getAttributes().get("accessKey"); if (accessChar != null) { out.writeAttribute("accessKey", accessChar.toString(), null); } out.startElement("span", component); String radioSpanClass = getFieldTextClass(); if (disabled) { radioSpanClass = SkinSelectors.AF_FIELD_TEXT_DISABLED_STYLE_CLASS; } XhtmlLafRenderer.renderStyleClassAttribute(rCtx, radioSpanClass); writeLabel(out, detailItem, (String) detailItem.getAttributes().get("text")); out.endElement("span"); out.endElement("label"); out.endElement("span"); out.endElement("td"); out.endElement("tr"); } // For Non-JavaScript browsers, render a input element(type= submit) to // submit the page. Encode the name attribute with the parameter name // and value thus it would enable the browsers to include the name of // this element in its payLoad if it submits the page. if (!XhtmlRenderer.supportsScripting(RenderingContext.getCurrentInstance())) { out.startElement("tr", component); out.startElement("td", component); if (BaseLafUtils.isRightToLeft(rCtx)) { out.writeAttribute("align", "right", null); } else { out.writeAttribute("align", "left", null); } out.writeAttribute("valign", "top", null); out.writeAttribute("nowrap", Boolean.TRUE, null); String nameAttri = XhtmlUtils.getEncodedParameter(XhtmlConstants.MULTIPLE_VALUE_PARAM) + XhtmlUtils.getEncodedParameter(compId) + XhtmlUtils.getEncodedParameter(XhtmlConstants.EVENT_PARAM) + XhtmlConstants.SHOW_EVENT; out.startElement("span", null); out.startElement("input", null); out.writeAttribute("value", XhtmlConstants.NO_JS_PARAMETER_KEY_BUTTON, null); out.writeAttribute("type", "submit", null); out.writeAttribute("name", nameAttri, null); out.endElement("input"); out.endElement("span"); out.endElement("td"); out.endElement("tr"); } out.endElement("table"); out.endElement("td"); } /** * Gets onclick javascript to be associated with radio onlcick event. * * <p>Checks if component is contained within a form, if not, returns null. Further, checks if PPR * is supported and returns a script to be called for this case else returns a script where PPR is * not required. */ private String _getRadioSubmitJS( UIComponent component, UIXRenderingContext rCtx, String formName, String compId, String detailChildId, boolean isImmediate) { if (formName == null) { _LOG.warning("PAGE_NOT_CONTAIN_FORM_ELEMENT"); return null; } String validate = "1"; if (isImmediate) { validate = "0"; } // Check if PPR enabled, do a _submitPartialChange, else do a formSubmit. String onClickHandler = ""; boolean pprEnabled = elementSupportsPartial(rCtx, compId); if (pprEnabled) { // PH:If agent is of type PDA, call submitForm instead of doing a full // page submission since PPR on this component is not supported although // pprEnabled is true for PIE and IE Mobile if (CoreRenderer.isPDA(RenderingContext.getCurrentInstance())) { StringBuilder jsBuff = new StringBuilder(135); jsBuff .append("submitForm('") .append(formName) .append("',") .append(validate) .append(",{event:'show',source:'") .append(detailChildId) .append("'});return true;"); onClickHandler = jsBuff.toString(); } else { StringBuilder jsBuff = new StringBuilder(220); jsBuff .append("_submitPartialChange('") .append(formName) .append("',") .append(validate) .append(", {event:'show',source:'") .append(detailChildId) .append("'});return true;"); onClickHandler = jsBuff.toString(); } } else { StringBuilder jsBuff = new StringBuilder(135); jsBuff .append("submitForm('") .append(formName) .append("',") .append(validate) .append(",{event:'show',source:'") .append(detailChildId) .append("'});return true;"); onClickHandler = jsBuff.toString(); } return onClickHandler; } private static final String _RADIO_TABLE_SUFFIX_ID_CONST = "_sor_tbl"; private static final String _RADIO_SPAN_SUFFIX_ID_CONST = _RADIO_TABLE_SUFFIX_ID_CONST + "_span"; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(CorePanelRadioRenderer.class); }
/** * Change specialization for re-ordering of children. While applying this Change, the specified * order of children is restored. * * @version $Name: $ ($Revision: * adfrt/faces/adf-faces-api/src/main/java/oracle/adf/view/faces/change/ReorderChildrenComponentChange.java#0 * $) $Date: 10-nov-2005.19:10:01 $ */ public class ReorderChildrenComponentChange extends ComponentChange implements DocumentChange { /** * Constructs a ReorderChange with the given List of identifiers for children. * * @param childIds An in-order collection (List) of Ids (as java.lang.String) of child components. * This List implementation should be of type java.io.Serializable in order to be persisted. * If no identifier was passed, it would be assumed that the list consists of the Ids. * @throws IllegalArgumentException if supplied childIds were to be null. */ public ReorderChildrenComponentChange(List<String> childIds) { this(childIds, "id"); } /** * Constructs a ReorderChange with the given List of identifiers for children. * * @param childIds An in-order collection (List) of Ids (as java.lang.String) of child components. * This List implementation should be of type java.io.Serializable in order to be persisted. * @param identifier Determines the type of identifiers which the List consists of. * @throws IllegalArgumentException if supplied childIds were to be null or supplied identifier * was to be null or emtpy string. */ public ReorderChildrenComponentChange(List<String> childIds, String identifier) { if (childIds == null) throw new IllegalArgumentException( _LOG.getMessage("CANNOT_CONSTRUCT_REORDERCHANGE_WITH_NULL_ID")); if (identifier == null || "".equals(identifier)) throw new IllegalArgumentException(_LOG.getMessage("IDENTIFIER_TYPE_CANNOT_BE_NULL")); // make serializable copy of list _childIds = Collections.unmodifiableList(new ArrayList<String>(childIds)); _identifier = identifier; } /** Returns an unmodifiable List of the identifiers for the children. */ public List<String> getChildIds() { return _childIds; } /** Returns the identifier type. */ public final String getIdentifier() { return _identifier; } /** * {@inheritDoc} In case children were to be removed between the time when this Change was added, * and the time when it was applied, maybe due to application of a RemoveChildrenChange, such * children are not re-instated. In case children were to be added between the time when this * Change was added, and the time when it was applied, maybe due to application of an * AddChildChange, such children are appended to the end of the list in preserving the order in * which they were added (that is they appear at the end). */ @SuppressWarnings("unchecked") @Override public void changeComponent(UIComponent uiComponent) { int childCount = uiComponent.getChildCount(); if (childCount == 0) return; // build order map of of current Nodes, keyed by id Map<String, UIComponent> childrenMap = new LinkedHashMap<String, UIComponent>(); List<UIComponent> children = uiComponent.getChildren(); int fakeIndex = 0; for (UIComponent child : children) { String attrValue = (String) child.getAttributes().get(_identifier); // create a dummy key to maintain order of children whose identifier // does not exist if (attrValue == null) { attrValue = Integer.valueOf(fakeIndex++).toString(); } childrenMap.put(attrValue, child); } // remove the children so that we can add them back in children.clear(); // // put children back in, in order // for (String currReorderID : _childIds) { UIComponent currChild = childrenMap.remove(currReorderID); if (currChild != null) { children.add(currChild); } } // add in all of the rest of the children in // relative order they originally appeared children.addAll(childrenMap.values()); } /** * {@inheritDoc} In case children were to be removed between the time when this Change was added, * and the time when it was applied, maybe due to application of a RemoveChildrenChange, such * children are not re-instated. In case children were to be added between the time when this * Change was added, and the time when it was applied, maybe due to application of an * AddChildChange, such children are appended to the end of the list in preserving the order in * which they were added (that is they appear at the end). */ public void changeDocument(Node componentNode) { // build order map of of current Nodes, keyed by id LinkedHashMap<String, Node> currChildrenMap = new LinkedHashMap<String, Node>(13); Node currChild = componentNode.getFirstChild(); int fakeIndex = 0; while (currChild != null) { NamedNodeMap attributes = currChild.getAttributes(); String currKey = null; if (attributes != null) { Node idAttr = attributes.getNamedItem(_identifier); if (idAttr != null) { currKey = idAttr.getNodeValue(); } } // create a dummy key to maintain order of non-ided children if (currKey == null) { // =-= bts What about insignificant whitespace? currKey = Integer.valueOf(fakeIndex++).toString(); } currChildrenMap.put(currKey, currChild); // remove the children so that we can add them back in componentNode.removeChild(currChild); // next node is first node again currChild = componentNode.getFirstChild(); } // // put children back in, in order // for (String currReorderID : _childIds) { currChild = currChildrenMap.remove(currReorderID); if (currChild != null) { componentNode.appendChild(currChild); } } // add in all of the rest of the children in // relative order they originally appeared for (Map.Entry<String, Node> entry : currChildrenMap.entrySet()) { componentNode.appendChild(entry.getValue()); } } /** Returns true if adding the DocumentChange should force the JSP Document to reload */ public boolean getForcesDocumentReload() { return false; } private final List<String> _childIds; private final String _identifier; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ReorderChildrenComponentChange.class); private static final long serialVersionUID = 1L; }
/** * Base class for Renderers that generate images. * * @version $Name: $ ($Revision$) $Date$ * @deprecated This class comes from the old Java 1.2 UIX codebase and should not be used anymore. */ @Deprecated abstract class GeneratedImageRenderer extends HtmlLafRenderer implements ImageConstants { protected void renderImage( UIXRenderingContext context, UINode node, ImageProviderResponse response) throws IOException { renderImage(context, node, response, null); } /** * we do not want shortDesc rendered by XhtmlLafRenderer as this puts it as the title attribute; * instead we write shortDesc as the alt text of the image. */ @Override protected void renderShortDesc(UIXRenderingContext context, UINode node) {} protected void renderImage( UIXRenderingContext context, UINode node, ImageProviderResponse response, String mapName) throws IOException { // We assume that we have an image to render assert (response != null); boolean disabled = isDisabled(context, node); boolean hasMap = (response.getMapAreas() != null); Object shortDesc = getShortDesc(context, node); boolean hasLink = !disabled && !hasMap; Object destination = hasLink ? getDestination(context, node) : null; renderImage(context, node, response, hasMap, mapName, shortDesc, destination); } protected void renderImage( UIXRenderingContext context, UINode node, ImageProviderResponse response, boolean hasMap, String mapName, Object shortDesc, Object destination) throws IOException { assert node != null; boolean hasLink = (destination != null); Object longDesc = getLongDesc(context, node); String imageStyle = getImageStyle(context, node); String imageStyleClass = getImageStyleClass(context, node); ResponseWriter writer = context.getResponseWriter(); UIComponent component = (node == null) ? null : node.getUIComponent(); if (hasLink) { writer.startElement("a", component); renderEncodedActionURI(context, "href", destination); renderAttribute(context, node, "target", TARGET_FRAME_ATTR); // Don't render access key on Netscape... Netscape doesn't // support access keys - if this ever changes, it would // be confusing if we rendered the accessKey attr without // also underlining the access key in the corresponding text. if (!isNetscape(context)) { renderButtonAccessKey(context, node); } // If we have a link, we render the standard attributes on // the link instead of on the image renderAttributes(context, node); } writer.startElement("img", component); // Write out all of the standard attrs if (!hasLink) renderAttributes(context, node); // Write out the image url writeCacheImageURI(context, "src", response.getImageURI()); // Write out the description attrs. renderAltAndTooltipForImage(context, shortDesc); renderAttribute(context, "longdesc", longDesc); // Null out the border renderAttribute(context, "border", "0"); // Render alignment. Is this necessary? renderHAlign(context, node); // This is to address bug #2047577 // Instead of adding an attribute to control placement of the button, // we just force it to middle (which is what everybody wants anyway). // We have to make sure we don't put the align attribute in twice. // We allow the hAlign attribute to take precedence. if (node.getAttributeValue(context, H_ALIGN_ATTR) == null) { Object valign = getVAlign(context, node); if (valign != null) renderAttribute(context, "align", valign); } // Render the width/height int width = response.getWidth(); int height = response.getHeight(); if (width != ImageProviderResponse.UNKNOWN_SIZE) renderAttribute(context, "width", IntegerUtils.getString(width)); if (height != ImageProviderResponse.UNKNOWN_SIZE) renderAttribute(context, "height", IntegerUtils.getString(height)); // The image map if (hasMap) writer.writeAttribute("usemap", "#" + mapName, null); if (imageStyle != null) renderAttribute(context, "style", imageStyle); if (imageStyleClass != null) renderStyleClassAttribute(context, imageStyleClass); writer.endElement("img"); if (hasLink) writer.endElement("a"); } @Override protected Object getText(UIXRenderingContext context, UINode node) { return node.getAttributeValue(context, TEXT_ATTR); } @Override protected Object getShortDesc(UIXRenderingContext context, UINode node) { Object desc = node.getAttributeValue(context, SHORT_DESC_ATTR); if ((desc == null) && !isInaccessibleMode(context)) { return getText(context, node); } return desc; } protected Object getImageName(UIXRenderingContext context, UINode node) { return node.getAttributeValue(context, ID_ATTR); } protected Object getLongDesc(UIXRenderingContext context, UINode node) { return node.getAttributeValue(context, LONG_DESC_URL_ATTR); } /** Returns the destination to use for the GeneratedImageRenderer */ protected Object getDestination(UIXRenderingContext context, UINode node) { if (!supportsNavigation(context)) return null; Object destination = node.getAttributeValue(context, DESTINATION_ATTR); // If we have an onclick handler, always provide a destination if ((destination == null) && supportsIntrinsicEvents(context)) { Object onClick = getOnClick(context, node); if (onClick != null) { destination = "#"; } } return destination; } protected String getImageStyle(UIXRenderingContext context, UINode node) { return null; } protected String getImageStyleClass(UIXRenderingContext context, UINode node) { return null; } protected void renderButtonAccessKey(UIXRenderingContext context, UINode node) throws IOException { renderAttribute(context, node, "accesskey", ACCESS_KEY_ATTR); } protected static String getURLAttribute( UIXRenderingContext context, UINode node, AttributeKey attrKey) { Object o = node.getAttributeValue(context, attrKey); if (o != null) return o.toString(); return null; } // Returns the style for the specified name protected static Style getStyle(UIXRenderingContext context, UINode node, String name) { if (name == null) return null; StyleMap map = context.getStyleContext().getStyleMap(); if (map == null) return null; return map.getStyleByName(context.getStyleContext(), name); } // Returns the vertical alignment protected Object getVAlign(UIXRenderingContext context, UINode node) { return null; } protected static int getFontStyle( UIXRenderingContext context, UINode node, Style classStyle, Style inlineStyle, String styleName) { int fontStyle = Font.PLAIN; int fontWeight = Font.PLAIN; boolean gotStyle = false; boolean gotWeight = false; Object value = null; // First, try getting font-style and font-weight from inline style if (inlineStyle != null) { value = _parseValue(inlineStyle, null, Style.FONT_STYLE_KEY); if (value != null) { fontStyle = _getAWTFontStyle(value); gotStyle = true; } value = _parseValue(inlineStyle, null, Style.FONT_WEIGHT_KEY); if (value != null) { fontWeight = _getAWTFontWeight(value); gotWeight = true; } } if (classStyle != null) { if (!gotStyle) { value = _parseValue(classStyle, styleName, Style.FONT_STYLE_KEY); if (value != null) fontStyle = _getAWTFontStyle(value); } if (!gotWeight) { value = _parseValue(classStyle, styleName, Style.FONT_WEIGHT_KEY); if (value != null) fontWeight = _getAWTFontWeight(value); } } return (fontStyle | fontWeight); } protected static int getFontSize( UIXRenderingContext context, UINode node, Style classStyle, Style inlineStyle, String styleName) { // First, try size from inline font if (inlineStyle != null) { Object value = _parseValue(inlineStyle, null, Style.FONT_SIZE_KEY); if (value instanceof Integer) return ((Integer) value).intValue(); } if (styleName != null) { Object value = _parseValue(classStyle, styleName, Style.FONT_SIZE_KEY); if (value instanceof Integer) return ((Integer) value).intValue(); } return _DEFAULT_FONT_SIZE; } @SuppressWarnings("unchecked") protected static Collection<Object> getFontFamilies( UIXRenderingContext context, UINode node, Style style, String styleName) { if (style != null) { if (_parseValue(style, null, Style.FONT_FAMILIES_KEY) instanceof Collection) { return (Collection<Object>) _parseValue(style, null, Style.FONT_FAMILIES_KEY); } else { Collection<Object> parsedValueList = new ArrayList<Object>(); parsedValueList.add(_parseValue(style, null, Style.FONT_FAMILIES_KEY)); return parsedValueList; } } return null; } protected static Color getBackground( UIXRenderingContext context, UINode node, Style classStyle, Style inlineStyle, String styleName) { if (inlineStyle != null) { Color background = (Color) _parseValue(inlineStyle, null, Style.BACKGROUND_KEY); if (background != null) return background; } return (Color) _parseValue(classStyle, styleName, Style.BACKGROUND_KEY); } protected static Color getForeground( UIXRenderingContext context, UINode node, Style classStyle, Style inlineStyle, String styleName) { if (inlineStyle != null) { Color foreground = (Color) _parseValue(inlineStyle, null, Style.FOREGROUND_KEY); if (foreground != null) return foreground; } return (Color) _parseValue(classStyle, styleName, Style.FOREGROUND_KEY); } protected static Color getSurroundingColor(UIXRenderingContext context) { if (BaseDesktopUtils.supportsTransparentImages(context)) return null; return BaseDesktopUtils.getBackgroundColor(context); } protected static boolean isTextAntialiased( UIXRenderingContext context, UINode node, Style classStyle, Style inlineStyle) { if (inlineStyle != null) { Object value = inlineStyle.getParsedProperty(Style.TEXT_ANTIALIAS_KEY); return Boolean.TRUE.equals(value); } if (classStyle != null) { Object value = classStyle.getParsedProperty(Style.TEXT_ANTIALIAS_KEY); return Boolean.TRUE.equals(value); } return false; } private static Object _parseValue(Style style, String styleName, ParsedPropertyKey key) { if (style == null) return null; Object value = null; try { value = style.getParsedProperty(key); } catch (PropertyParseException e) { if (_LOG.isWarning()) _LOG.warning( styleName == null ? "Error while parsing inline style" : "Error while parsing style class \"" + styleName + "\"", e); } return value; } private static int _getAWTFontStyle(Object style) { if (style == Style.ITALIC_FONT_STYLE) return Font.ITALIC; return Font.PLAIN; } private static int _getAWTFontWeight(Object weight) { if (weight == Style.BOLD_FONT_WEIGHT) return Font.BOLD; return Font.PLAIN; } private static final int _DEFAULT_FONT_SIZE = 12; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(GeneratedImageRenderer.class); }
class PageFlowScopeMap implements Map<String, Object>, Serializable { /** Return a PageFlowScopeMap stored with a token. */ public static PageFlowScopeMap getPageFlowScopeMap( FacesContext context, String token, int lifetime) { TokenCache cache = _getRootTokenCache(context, lifetime); PageFlowScopeMap map = _getPageFlowScopeMap(context, cache, token); if (_LOG.isFine()) { _LOG.fine( "pageFlowScope: found map {0} at token {1}", new Object[] {(map == null) ? (Object) "null" : map, token}); } if (map == null) { return null; } else { // Don't return the same instance of PageFlowScopeMap as was used // on the previous page; otherwise, for instance, we'll overwrite // its token as we mutate. Instead, create a new PageFlowScopeMap, // but reuse the _map; we'll clone the _map itself if we mutate return new PageFlowScopeMap(map._map, token, map._sharedData); } } private static PageFlowScopeMap _getPageFlowScopeMap( FacesContext context, TokenCache cache, String token) { if (token == null) throw new NullPointerException(); int lastSeparator = token.lastIndexOf(TokenCache.SEPARATOR_CHAR); String parentToken; String childToken; if (lastSeparator < 0) { parentToken = null; childToken = token; } else { parentToken = token.substring(0, lastSeparator); childToken = token.substring(lastSeparator + 1); } Map<String, Object> storeMap = _createMapToStore(context, parentToken); return (PageFlowScopeMap) storeMap.get(childToken); } /** Only for serialization */ public PageFlowScopeMap() {} public PageFlowScopeMap(int lifetime) { this(new HashMap<String, Object>(13), null, new SharedData(lifetime)); } private PageFlowScopeMap(HashMap<String, Object> map, String token, SharedData sharedData) { _map = map; _sharedData = sharedData; _token = token; } // // Create a PageFlowScopeMap pointing at a parent // private PageFlowScopeMap(PageFlowScopeMap parent, boolean copyParent) { assert (parent != null); _sharedData = new SharedData(parent._sharedData._lifetime); _sharedData._parent = parent; _map = new HashMap<String, Object>(); if (copyParent) _map.putAll(parent._map); } public PageFlowScopeMap getParent() { return _sharedData._parent; } public synchronized String getToken(FacesContext context) { if (_token != null) return _token; // Don't need a token when nothing's in the map, and we // don't have a parent if (isEmpty() && (_sharedData._children == null) && (_sharedData._parent == null)) return null; String parentToken; TokenCache cache; if (_sharedData._parent != null) { parentToken = _sharedData._parent.getToken(context); cache = _sharedData._parent._getTokenCache(); } else { parentToken = null; cache = _getRootTokenCache(context, _sharedData._lifetime); } Map<String, Object> store = _createMapToStore(context, parentToken); String token = cache.addNewEntry(this, store); if (parentToken != null) token = parentToken + TokenCache.SEPARATOR_CHAR + token; _token = token; // With a new token, there cannot be any shared children // with a prior request. if (_sharedData._children != null) { // =-=AEW NEED TO CLONE SHARED DATA _LOG.fine("Discarding child PageFlowScopes; new token is {0}", token); _sharedData._children = null; } return _token; } @SuppressWarnings("unchecked") private static Map<String, Object> _createMapToStore(FacesContext context, String parentToken) { String fullToken; if (parentToken == null) { fullToken = _PAGE_FLOW_SCOPE_CACHE + TokenCache.SEPARATOR_CHAR; } else { fullToken = (_PAGE_FLOW_SCOPE_CACHE + TokenCache.SEPARATOR_CHAR + parentToken + TokenCache.SEPARATOR_CHAR); } return new SubKeyMap(context.getExternalContext().getSessionMap(), fullToken); } @Override public boolean equals(Object o) { if (o instanceof PageFlowScopeMap) o = ((PageFlowScopeMap) o)._map; return _map.equals(o); } @Override public int hashCode() { return _map.hashCode(); } public int size() { return _map.size(); } public boolean isEmpty() { return _map.isEmpty(); } public boolean containsKey(Object key) { return _map.containsKey(key); } public boolean containsValue(Object value) { return _map.containsValue(value); } public Collection<Object> values() { // Use an unmodifiableCollection to save me the headache // of catching mutations return Collections.unmodifiableCollection(_map.values()); } public Set<Map.Entry<String, Object>> entrySet() { // Use an unmodifiableSet to save me the headache // of catching mutations return Collections.unmodifiableSet(_map.entrySet()); } public Set<String> keySet() { // Use an unmodifiableSet to save me the headache // of catching mutations return Collections.unmodifiableSet(_map.keySet()); } public Object get(Object key) { return _map.get(key); } public Object put(String key, Object value) { _detachIfNeeded(); if (_LOG.isFine()) { _LOG.fine("pageFlowScope: put({0}, {1})", new Object[] {key, value}); } return _map.put(key, value); } public Object remove(Object key) { _detachIfNeeded(); if (_LOG.isFine()) { _LOG.fine("pageFlowScope: remove({0})", key); } return _map.remove(key); } public void putAll(Map<? extends String, ? extends Object> t) { _detachIfNeeded(); if (_LOG.isFine()) { _LOG.fine("pageFlowScope: putAll({0})", t); } _map.putAll(t); } public void clear() { _detachIfNeeded(); if (_LOG.isFine()) { _LOG.fine("pageFlowScope: clear()"); } _map.clear(); } public PageFlowScopeMap createChild(boolean copyParent) { return new PageFlowScopeMap(this, copyParent); } public void discard() { FacesContext context = FacesContext.getCurrentInstance(); String token = getToken(context); int lastSeparator = token.lastIndexOf(TokenCache.SEPARATOR_CHAR); String parentToken; String childToken; if (lastSeparator < 0) { parentToken = null; childToken = token; } else { parentToken = token.substring(0, lastSeparator); childToken = token.substring(lastSeparator + 1); } // Remove ourselves if (_sharedData._parent != null) { Map<String, Object> storeMap = _createMapToStore(context, parentToken); _sharedData._parent._sharedData._children.removeOldEntry(childToken, storeMap); } // And clean up all of our children _removeAllChildren(context, token); } private void _removeAllChildren(FacesContext context, String token) { // Clear everything - note that because of naming conventions, // this will in fact automatically recurse through all children // grandchildren etc. - which is kind of a design flaw of SubKeyMap, // but one we're relying on Map<String, Object> store = _createMapToStore(context, token); store.clear(); _sharedData._children = null; } @Override public String toString() { return "PageFlowScopeMap@" + System.identityHashCode(this) + "[_map=" + _map + ", _token=" + _token + ",_children=" + _sharedData._children + "]"; } private static TokenCache _getRootTokenCache(FacesContext context, int lifetime) { return TokenCache.getTokenCacheFromSession( context.getExternalContext(), _PAGE_FLOW_SCOPE_CACHE, true, lifetime); } private TokenCache _getTokenCache() { if (_sharedData._children == null) _sharedData._children = new TokenCache(_sharedData._lifetime); return _sharedData._children; } // =-=AEW This strategy assumes that the PageFlowScopeMap // will be inherited from a prior request, have things // added and removed prior to Render Response *without // the token being requested*, then have the token used // repeatedly during Render Response *without further // mutations*. Both of these assumptions seem very // dubious! @SuppressWarnings("unchecked") private void _detachIfNeeded() { if (_token != null) { _map = (HashMap<String, Object>) _map.clone(); _token = null; // =-=AEW When do we discard children? } } public static class SharedData implements Serializable { public SharedData() {} public SharedData(int lifetime) { _lifetime = lifetime; } private int _lifetime; // =-=AEW Make transient for efficiency private PageFlowScopeMap _parent; private TokenCache _children; private static final long serialVersionUID = 1L; } // DELETE AFTER DIALOG SERVICE IS CLEANED UP boolean __invalid; private SharedData _sharedData; private String _token; private HashMap<String, Object> _map; private static final String _PAGE_FLOW_SCOPE_CACHE = "org.apache.myfaces.trinidadinternal.application.PageFlowScope"; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(PageFlowScopeMap.class); private static final long serialVersionUID = 1L; }
public class TableSelectOneRenderer extends XhtmlRenderer { public TableSelectOneRenderer(FacesBean.Type type) { super(type); } @Override protected void findTypeConstants(FacesBean.Type type) { super.findTypeConstants(type); _renderer = createCellRenderer(type); } // // Decode // @SuppressWarnings("unchecked") @Override protected void decode( FacesContext facesContext, UIComponent component, @SuppressWarnings("unused") FacesBean facesBean, @SuppressWarnings("unused") String clientId) { UIXCollection table = (UIXCollection) component; Object oldKey = table.getRowKey(); try { // Set the row key to null to force the clientId to be correct table.setRowKey(null); String selectionParam = __getSelectionParameterName(facesContext, table); Map<String, String> parameters = facesContext.getExternalContext().getRequestParameterMap(); _LOG.finest("Params:{0}", parameters); String selection = parameters.get(selectionParam); if (selection != null) { final RowKeySet state; if (table instanceof UIXTable) state = ((UIXTable) table).getSelectedRowKeys(); else state = ((UIXTree) table).getSelectedRowKeys(); table.setClientRowKey(selection); // If the key is not already selected, or the state is more than one // (someone changed the table selection from multiple to single), // update the keys if (!state.isContained() || state.size() > 1) { RowKeySet unselected = state.clone(); // TODO : do not mutate the selectedRowKeys here. // instead, mutate when event is broadcast: state.clear(); state.add(); // clone, so that subsequent mutations of "state" will // not affect the parameters of this event: bug 4733858: RowKeySet selected = state.clone(); FacesEvent event = new SelectionEvent(table, unselected, selected); event.queue(); } } } finally { table.setRowKey(oldKey); } } // // Encode // @Override public boolean getRendersChildren() { return true; } @Override protected void encodeAll( FacesContext context, RenderingContext rc, UIComponent component, FacesBean bean) throws IOException { TableRenderingContext tContext = TableRenderingContext.getCurrentInstance(); if (tContext == null) { _LOG.severe("TABLESELECT_COMPONENT_MAY_ONLY_INSIDE_TABLE_AND_TREETABLE"); return; } RenderStage stage = tContext.getRenderStage(); switch (stage.getStage()) { case RenderStage.SUB_CONTROL_BAR_STAGE: case RenderStage.UPPER_CONTROL_BAR_STAGE: case RenderStage.LOWER_CONTROL_BAR_STAGE: break; case RenderStage.DATA_STAGE: renderCellContent(context, rc, tContext, component, bean); break; default: throw new AssertionError("bad renderStage:" + stage.getStage()); } } protected boolean isSelectOne() { return true; } protected CoreRenderer createCellRenderer(FacesBean.Type type) { return new Radio(type); } protected void renderCellContent( FacesContext context, RenderingContext rc, TableRenderingContext tContext, UIComponent component, FacesBean bean) throws IOException { rc.setCurrentClientId(tContext.getTableId()); delegateRenderer(context, rc, component, bean, _renderer); rc.setCurrentClientId(null); } /** Get the name of the parameter for the selection; package-private for testing. */ static String __getSelectionParameterName(FacesContext context, UIComponent table) { return (table.getClientId(context) + NamingContainer.SEPARATOR_CHAR + XhtmlConstants.SELECTED_KEY); } public static class Radio extends SimpleSelectBooleanCheckboxRenderer { public Radio(FacesBean.Type type) { super(type); } @Override protected String getCompositeId(String clientId) { return null; } /** we do not want to render the simple span for the checkbox. */ @Override protected boolean getRenderSimpleSpan(UIComponent component, FacesBean bean) { return false; } /** don't render a special content style class on the radio. */ @Override protected String getContentStyleClass(UIComponent component, FacesBean bean) { return null; } @Override protected void renderId(FacesContext context, UIComponent component) throws IOException { TableRenderingContext tContext = TableRenderingContext.getCurrentInstance(); String param = (tContext.getTableId() + NamingContainer.SEPARATOR_CHAR + XhtmlConstants.SELECTED_KEY); ResponseWriter writer = context.getResponseWriter(); writer.writeAttribute("name", param, null); // =-=AEW Inefficient. We only need the "id" when there's // a shortDescription (which is when we'll get a label) if (getShortDesc(component, getFacesBean(component)) != null) writer.writeAttribute("id", getClientId(context, component), null); } @Override protected String getClientId(FacesContext context, UIComponent component) { // We use the table's container client ID return component.getContainerClientId(context); } @Override protected Object getSubmittedValue(UIComponent component, FacesBean bean) { TableRenderingContext tContext = TableRenderingContext.getCurrentInstance(); return tContext.getSelectedRowKeys().isContained() ? Boolean.TRUE : Boolean.FALSE; } @Override protected Object getType() { return "radio"; } @Override protected Object getValueAttr(RenderingContext rc) { TableRenderingContext tContext = TableRenderingContext.getCurrentInstance(); return ((UIXCollection) tContext.getCollectionComponent()).getClientRowKey(); } @Override protected String getShortDesc(UIComponent component, FacesBean bean) { String key = getDefaultShortDescKey(); RenderingContext arc = RenderingContext.getCurrentInstance(); return arc.getTranslatedString(key); } protected String getDefaultShortDescKey() { return "af_tableSelectOne.SELECT_COLUMN_HEADER"; } @Override protected char getAccessKey(UIComponent component, FacesBean bean) { return CHAR_UNDEFINED; } @Override protected boolean isImmediate(UIComponent component, FacesBean bean) { TableRenderingContext tContext = TableRenderingContext.getCurrentInstance(); return tContext.isImmediate(); } @Override protected boolean getReadOnly(FacesContext context, UIComponent component, FacesBean bean) { return false; } @Override protected boolean getDisabled(UIComponent component, FacesBean bean) { return false; } /** @todo Support? */ @Override protected String getOnblur(UIComponent component, FacesBean bean) { return null; } /** @todo Support? */ @Override protected String getOnfocus(UIComponent component, FacesBean bean) { return null; } @Override protected String getOnchange(UIComponent component, FacesBean bean) { return null; } protected String getOnselect(UIComponent component, FacesBean bean) { return null; } @Override protected String getText(UIComponent component, FacesBean bean) { return null; } } private CoreRenderer _renderer; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(TableSelectOneRenderer.class); }
public class FileDownloadActionListenerTag extends TrinidadTagSupport { public void setContentType(ValueExpression contentType) { _contentType = contentType; } public void setFilename(ValueExpression filename) { _filename = filename; } public void setMethod(MethodExpression method) { _method = method; } @Override public int doStartTag() throws JspException { UIComponentTag tag = UIComponentTag.getParentUIComponentTag(pageContext); if (tag == null) { throw new JspException( _LOG.getMessage("FILEDOWNLOADACTIONLISTENER_MUST_INSIDE_UICOMPONENT_TAG")); } // Only run on the first time the tag executes if (!tag.getCreated()) return SKIP_BODY; UIComponent component = tag.getComponentInstance(); if (!(component instanceof ActionSource)) { throw new JspException( _LOG.getMessage("FILEDOWNLOADACTIONLISTENER_MUST_INSIDE_UICOMPONENT_TAG")); } ELContextTag parentELContext = (ELContextTag) findAncestorWithClass(this, ELContextTag.class); Application application = FacesContext.getCurrentInstance().getApplication(); FileDownloadActionListener listener = new FileDownloadActionListener(); if (_filename != null) { listener.setValueExpression(FileDownloadActionListener.FILENAME_KEY, _filename); } if (_contentType != null) { listener.setValueExpression(FileDownloadActionListener.CONTENT_TYPE_KEY, _contentType); } listener.setMethod(_method); ((ActionSource) component).addActionListener(listener); return super.doStartTag(); } @Override public void release() { super.release(); _contentType = null; _filename = null; _method = null; } private ValueExpression _contentType; private ValueExpression _filename; private MethodExpression _method; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(FileDownloadActionListenerTag.class); }
/** This parses a skin css file into namespace map and selector/properties. */ public class SkinCSSParser { public SkinCSSParser() {} public void parseCSSDocument(Reader in, SkinCSSDocumentHandler documentHandler) { try { CSSScanner scanner = new CSSScanner(in); documentHandler.startDocument(); List<String> selectorList = null; // start scanning the document // return comments /* xxx */ // return @rules, which end with ';' // return selectors, which end with a { // return properties, which end with a } int currentType = _nextIgnoreSpaces(scanner); while (currentType != CSSLexicalUnits.EOF) { if (currentType == CSSLexicalUnits.COMMENT) documentHandler.comment(scanner.getStringValue()); else if (currentType == CSSLexicalUnits.AT_KEYWORD) documentHandler.atRule(scanner.getStringValue()); else if (currentType == CSSLexicalUnits.LEFT_CURLY_BRACE) { documentHandler.startSelector(); selectorList = _parseSelectorString(scanner.getStringValue()); } else if (currentType == CSSLexicalUnits.RIGHT_CURLY_BRACE) { String properties = scanner.getStringValue(); _handlePropertiesString(documentHandler, properties); if (selectorList == null) { if (_LOG.isWarning()) { _LOG.warning("IGNORING_PROPERTIES_WITHOUT_SELECTOR", properties); } } documentHandler.endSelector(selectorList); } currentType = _nextIgnoreSpaces(scanner); } } finally { documentHandler.endDocument(); } } /** * given a string that denotes the selectors in a css file, parse this further into a list of * selectors. (the selectors are deliminated by commas) */ private List<String> _parseSelectorString(String selectors) { // give a list of selectors, deliminated by commas, parse into a List. // loop thru each character until I get to a left bracket. if (selectors == null) return null; List<String> selectorList = new ArrayList<String>(); // pull apart by commas // don't skip whitespace since whitespace means descendant selectors in css String[] selector = _splitString(selectors, ',', false); String trimmedSelector; for (int i = 0; i < selector.length; i++) { // the first selector might have extra } // this is a common typo, to have extra }s. if (i == 0) { trimmedSelector = _trimChar(selector[i].trim(), '}'); } else { trimmedSelector = selector[i].trim(); } // skip the selector if it is empty if ("".equals(trimmedSelector)) { if (_LOG.isWarning()) _LOG.warning("ERR_PARSING_SKIN_SELECTOR", selectors); } else selectorList.add(trimmedSelector); } return selectorList; } /** * given a string that denotes the properties of one or more selectors, parse further into * name/value pairs and call documentHandler's property callback. */ private void _handlePropertiesString(SkinCSSDocumentHandler documentHandler, String properties) { if (properties == null) return; // first, parse out any comments Matcher matcher = _COMMENT_PATTERN.matcher(properties); properties = matcher.replaceAll(""); // split into name and value (don't skip whitespace since properties like padding: 0px 5px // need the spaces) String[] property = _splitString(properties, ';', false); for (int i = 0; i < property.length; i++) { int indexOfColon = property[i].indexOf(':'); if ((indexOfColon > -1) && (indexOfColon < property[i].length())) { String name = property[i].substring(0, indexOfColon); String value = property[i].substring(indexOfColon + 1); documentHandler.property(name.trim(), value.trim()); } } } /** * return the array of strings computed by splitting this string around matches of the given * character * * @param in * @param charDelimiter * @param skipWhitespace if true, whitespace is skipped and not included in the return Strings in * the String array. * @return String[] The array of Strings computed by splitting the input String around matches of * the charDelimiter */ private static String[] _splitString(String in, char charDelimiter, boolean skipWhitespace) { // return a String[] with each piece that is deliminated by the inChar. int length = in.length(); StringBuffer buffer = new StringBuffer(length); List<String> splitList = new ArrayList<String>(); for (int i = 0; i < length; i++) { char c = in.charAt(i); if (c == charDelimiter) { // we hit the delimiter, so put it in the splitList and start a new buffer. splitList.add(buffer.toString()); buffer = new StringBuffer(length); } else { // it's ok to put the character in the buffer if we don't want to skip whitespace // or if it isn't whitespace to begin with. if (!skipWhitespace || !(Character.isWhitespace(c))) buffer.append(c); } } // we are done with all the characters String lastString = buffer.toString(); if (lastString.length() > 0) splitList.add(lastString); return splitList.toArray(_EMPTY_STRING_ARRAY); } private static String _trimChar(String in, char c) { int len = in.length(); char currentChar = in.charAt(0); if (currentChar != c) return in; for (int i = 1; i < len; i++) { currentChar = in.charAt(i); if (currentChar != c) { return in.substring(i); } } return in; } // ignores spaces. private int _nextIgnoreSpaces(CSSScanner scanner) { int currentType = scanner.getNextToken(); while (currentType == CSSLexicalUnits.SPACE) { currentType = scanner.getNextToken(); } return currentType; } // This class builds up tokens for SPACE, COMMENT, AT_RULE, // LEFT_CURLY_BRACE (selectorList), and RIGHT_CURLY_BRACE (properties) // A token is stored in the _buffer object. private static class CSSScanner { public CSSScanner(Reader reader) { _reader = reader; } public String getStringValue() { if (_end <= 0) return null; else return new String(_buffer, 0, _end); } // get the next token in the buffer and return the type public int getNextToken() { _position = 0; _fillToken(); _end = _position; // strip off the final brace if needed if (_type == CSSLexicalUnits.RIGHT_CURLY_BRACE || _type == CSSLexicalUnits.LEFT_CURLY_BRACE) _end--; if (_currentChar == -1) return CSSLexicalUnits.EOF; return _type; } private void _fillToken() { while (true) { _nextChar(); switch (_currentChar) { case -1: _type = CSSLexicalUnits.EOF; break; case ' ': case '\t': case '\n': case '\f': case '\r': if (_type != CSSLexicalUnits.LEFT_CURLY_BRACE) { _type = CSSLexicalUnits.SPACE; return; } // fall through to LEFT_CURLY_BRACE case '/': if (_type != CSSLexicalUnits.LEFT_CURLY_BRACE) { // check for comment. If it is a comment, set the type and return // if it isn't a comment, keep looping to get more characters. _nextChar(); if (_currentChar == '*') { // WE ARE IN A COMMENT // loop and get characters into buffer until we get '*/' _nextChar(); int prevChar; while (_currentChar != -1) { prevChar = _currentChar; _nextChar(); if ((prevChar == '*') && (_currentChar == '/')) break; } _type = CSSLexicalUnits.COMMENT; return; } // wasn't a comment, so keep going on, filling the buffer with // each _nextChar call. break; } case '@': if (_type != CSSLexicalUnits.LEFT_CURLY_BRACE) { // found @. // @namespace is treated differently than other @rules. // These are the formats: // @namespace foo url(http://www.foo.com); // @agent { // af|inputText::content{color:red; background-color:blue;} // } // @platform {...} // If @namespace, go 'til the semi-colon // Else, go until the start/end brace match. // found @. keep getting characters until we get a ; or end of file. /* _nextChar(); while ((_currentChar != -1) && (_currentChar != ';')) { _nextChar(); } */ _nextChar(); // go until ; or until {} match int openBraceCount = 0; boolean openBraceCountStarted = false; while ((_currentChar != -1)) { if (_currentChar == '{') openBraceCount++; if (openBraceCount == 1) openBraceCountStarted = true; if (_currentChar == '}' && openBraceCountStarted) { openBraceCount--; if (openBraceCountStarted && openBraceCount == 0) { break; } } if (_currentChar == ';' && openBraceCount == 0) { break; } _nextChar(); } _type = CSSLexicalUnits.AT_KEYWORD; return; } default: if (_type == CSSLexicalUnits.LEFT_CURLY_BRACE) { // these are the properties, // keep going until we have all the properties while ((_currentChar != -1) && (_currentChar != '}')) { _nextChar(); } _type = CSSLexicalUnits.RIGHT_CURLY_BRACE; } else { while ((_currentChar != -1) && (_currentChar != '{')) { _nextChar(); } _type = CSSLexicalUnits.LEFT_CURLY_BRACE; } return; } // end switch if (_currentChar == -1) { _type = CSSLexicalUnits.EOF; return; } } } // fill buffer with one more character private void _nextChar() { try { _currentChar = _reader.read(); } catch (IOException e) { if (_LOG.isSevere()) { _LOG.severe("ERR_READING_SKIN_CSS_FILE", e); } _currentChar = -1; return; } // need to make sure buffer doesn't go over its size if (_buffer.length <= _position) { // increase buffer size by 50% char[] tmp = new char[_buffer.length + (_buffer.length / 2)]; // copy over buffer to new buffer for (int i = 0; i < _buffer.length; i++) tmp[i] = _buffer[i]; // pt _buffer to bigger buffer. _buffer = tmp; } _buffer[_position++] = (char) _currentChar; } private Reader _reader; // buffer parameters private char[] _buffer = new char[1024]; private int _position; private int _end; // type of token (it will be a CSSLexicalUnits constant) private int _type; // current character. -1 means EOF private int _currentChar; } /** constants that we use to keep track of what type of token of the css file we have parsed. */ private static class CSSLexicalUnits { public static final int EOF = 0; public static final int LEFT_CURLY_BRACE = 1; public static final int RIGHT_CURLY_BRACE = 2; public static final int SPACE = 3; public static final int COMMENT = 4; public static final int AT_KEYWORD = 5; } // this is the pattern for finding comments. We want to strip out // comments from the properties, and we use this pattern to do it. private static final Pattern _COMMENT_PATTERN = Pattern.compile("(?s)/\\*.*?\\*/"); private static final String[] _EMPTY_STRING_ARRAY = new String[0]; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(SkinCSSParser.class); }
/** Subclass of UIComponentTag to add convenience methods, and optimize where appropriate. */ public abstract class UIXComponentELTag extends UIComponentELTag { public UIXComponentELTag() {} public void setAttributeChangeListener(MethodExpression attributeChangeListener) { _attributeChangeListener = attributeChangeListener; } @Override public int doStartTag() throws JspException { int retVal = super.doStartTag(); // pu: There could have been some validation error during property setting // on the bean, this is the closest opportunity to burst out. if (_validationError != null) throw new JspException(_validationError); return retVal; } @Override protected final void setProperties(UIComponent component) { if (component instanceof UIViewRoot) { throw new IllegalStateException( "<f:view> was not present on this page; tag " + this + "encountered without an <f:view> being processed."); } super.setProperties(component); UIXComponent uixComponent = (UIXComponent) component; if (_attributeChangeListener != null) { uixComponent.setAttributeChangeListener(_attributeChangeListener); } setProperties(uixComponent.getFacesBean()); } protected void setProperty(FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { bean.setProperty(key, expression.getValue(null)); } else { bean.setValueExpression(key, expression); } } /** * Set a property of type java.lang.String[]. If the value is an EL expression, it will be stored * as a ValueExpression. Otherwise, it will parsed as a whitespace-separated series of strings. * Null values are ignored. */ protected void setStringArrayProperty( FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { bean.setProperty(key, _parseNameTokens(expression.getValue(null))); } else { bean.setValueExpression(key, expression); } } /** * Set a property of type java.util.List<java.lang.String>. If the value is an EL expression, it * will be stored as a ValueExpression. Otherwise, it will parsed as a whitespace-separated series * of strings. Null values are ignored. */ protected void setStringListProperty( FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { bean.setProperty(key, _parseNameTokensAsList(expression.getValue(null))); } else { bean.setValueExpression(key, expression); } } /** * Set a property of type java.util.Set<java.lang.String>. If the value is an EL expression, it * will be stored as a ValueExpression. Otherwise, it will parsed as a whitespace-separated series * of strings. Null values are ignored. */ protected void setStringSetProperty(FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { bean.setProperty(key, _parseNameTokensAsSet(expression.getValue(null))); } else { bean.setValueExpression(key, expression); } } /** * Set a property of type java.lang.Number. If the value is an EL expression, it will be stored as * a ValueBinding. Otherwise, it will parsed with Integer.valueOf() or Double.valueOf() . Null * values are ignored. */ protected void setNumberProperty(FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { Object value = expression.getValue(null); if (value != null) { if (value instanceof Number) { bean.setProperty(key, value); } else { String valueStr = value.toString(); if (valueStr.indexOf('.') == -1) bean.setProperty(key, Integer.valueOf(valueStr)); else bean.setProperty(key, Double.valueOf(valueStr)); } } } else { bean.setValueExpression(key, expression); } } /** * Set a property of type int[]. If the value is an EL expression, it will be stored as a * ValueExpression. Otherwise, it will parsed as a whitespace-separated series of ints. Null * values are ignored. */ protected void setIntArrayProperty(FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { Object value = expression.getValue(null); if (value != null) { String[] strings = _parseNameTokens(value); final int[] ints; if (strings != null) { try { ints = new int[strings.length]; for (int i = 0; i < strings.length; i++) { int j = Integer.parseInt(strings[i]); ints[i] = j; } } catch (NumberFormatException e) { _LOG.severe("CANNOT_CONVERT_INTO_INT_ARRAY", value); _LOG.severe(e); return; } } } } else { bean.setValueExpression(key, expression); } } /** * Set a property of type java.util.Date. If the value is an EL expression, it will be stored as a * ValueExpression. Otherwise, it will parsed as an ISO 8601 date (yyyy-MM-dd). Null values are * ignored. */ protected void setDateProperty(FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { bean.setProperty(key, _parseISODate(expression.getValue(null))); } else { bean.setValueExpression(key, expression); } } /** * Set a property of type java.util.Date. If the value is an EL expression, it will be stored as a * ValueBinding. Otherwise, it will parsed as an ISO 8601 date (yyyy-MM-dd) and the time * components (hour, min, second, millisecond) maximized. Null values are ignored. */ protected void setMaxDateProperty(FacesBean bean, PropertyKey key, ValueExpression expression) { if (expression == null) return; if (expression.isLiteralText()) { Date d = _parseISODate(expression.getValue(null)); Calendar c = Calendar.getInstance(); TimeZone tz = RequestContext.getCurrentInstance().getTimeZone(); if (tz != null) c.setTimeZone(tz); c.setTime(d); // Original value had 00:00:00 for hours,mins, seconds now maximize those // to get the latest time value for the date supplied. c.set(Calendar.HOUR_OF_DAY, 23); c.set(Calendar.MINUTE, 59); c.set(Calendar.SECOND, 59); c.set(Calendar.MILLISECOND, 999); bean.setProperty(key, c.getTime()); } else { bean.setValueExpression(key, expression); } } protected void setProperties(FacesBean bean) { // Could be abstract, but it's easier to *always* call super.setProperties(), // and perhaps we'll have something generic in here, esp. if we take // over "rendered" from UIComponentTag } /** * Sets any fatal validation error that could have happened during property setting. If this is * set, tag execution aborts with a JspException at the end of doStartTag(). * * @param validationError */ protected void setValidationError(String validationError) { _validationError = validationError; } /** * Parse a string into a java.util.Date object. The string must be in ISO 9601 format * (yyyy-MM-dd). */ private static final Date _parseISODate(Object o) { if (o == null) return null; String stringValue = o.toString(); try { return _getDateFormat().parse(stringValue); } catch (ParseException pe) { _LOG.info("CANNOT_PARSE_VALUE_INTO_DATE", stringValue); return null; } } /** * Parses a whitespace separated series of name tokens. * * @param stringValue the full string * @return an array of each constituent value, or null if there are no tokens (that is, the string * is empty or all whitespace) * @todo Move to utility function somewhere (ADF Share?) */ private static final String[] _parseNameTokens(Object o) { List<String> list = _parseNameTokensAsList(o); if (list == null) return null; return list.toArray(new String[list.size()]); } private static final List<String> _parseNameTokensAsList(Object o) { if (o == null) return null; String stringValue = o.toString(); ArrayList<String> list = new ArrayList<String>(5); int length = stringValue.length(); boolean inSpace = true; int start = 0; for (int i = 0; i < length; i++) { char ch = stringValue.charAt(i); // We're in whitespace; if we've just departed // a run of non-whitespace, append a string. // Now, why do we use the supposedly deprecated "Character.isSpace()" // function instead of "isWhitespace"? We're following XML rules // here for the meaning of whitespace, which specifically // EXCLUDES general Unicode spaces. if (Character.isWhitespace(ch)) { if (!inSpace) { list.add(stringValue.substring(start, i)); inSpace = true; } } // We're out of whitespace; if we've just departed // a run of whitespace, start keeping track of this string else { if (inSpace) { start = i; inSpace = false; } } } if (!inSpace) list.add(stringValue.substring(start)); if (list.isEmpty()) return null; return list; } private static final Set<String> _parseNameTokensAsSet(Object o) { List<String> list = _parseNameTokensAsList(o); if (list == null) return null; else return new HashSet(list); } private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(UIXComponentELTag.class); // We rely strictly on ISO 8601 formats private static DateFormat _getDateFormat() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); TimeZone tz = RequestContext.getCurrentInstance().getTimeZone(); if (tz != null) sdf.setTimeZone(tz); return sdf; } // No more used anywhere in Trinidad code, so deprecate since 2.0.x. @Deprecated public static final String DOCUMENT_CREATED_KEY = "org.apache.myfaces.trinidad.DOCUMENTCREATED"; private MethodExpression _attributeChangeListener; private String _validationError; }
/** * Utility class dealing with Locale-related issues, including common direction and alignment * constants. * * <p> * * @version $Name: $ ($Revision: * adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/util/nls/LocaleUtils.java#0 * $) $Date: 10-nov-2005.18:49:13 $ */ public final class LocaleUtils { /** Reading direction constant */ public static final int DIRECTION_DEFAULT = 0; /** Reading direction constant */ public static final int DIRECTION_LEFTTORIGHT = 1; /** Reading direction constant */ public static final int DIRECTION_RIGHTTOLEFT = 2; /** Conversion function to go from LocaleContext to the obsolete reading direction API. */ public static int getReadingDirection(LocaleContext localeContext) { return localeContext.isRightToLeft() ? DIRECTION_RIGHTTOLEFT : DIRECTION_LEFTTORIGHT; } /** Given a locale, returns the default reading direction. */ public static int getReadingDirectionForLocale(Locale loc) { if (loc == null) { loc = Locale.getDefault(); } String language = loc.getLanguage(); // arabic and hebrew are right-to-left languages. We treat "iw" as // hebrew because "iw" was the old code for Hebrew and the JDK // still uses it if (language.equals("ar") || language.equals("he") || language.equals("iw")) { return DIRECTION_RIGHTTOLEFT; } else { return DIRECTION_LEFTTORIGHT; } } /** Decodes an IANA string (e.g., en-us) into a Locale object. */ public static Locale getLocaleForIANAString(String ianaString) { if ((ianaString == null) || "".equals(ianaString)) return null; String language; String country = ""; String variant = ""; int dashIndex = ianaString.indexOf('-'); if (dashIndex < 0) { language = ianaString; } else { language = ianaString.substring(0, dashIndex); int start = dashIndex + 1; dashIndex = ianaString.indexOf('-', start); if (dashIndex < 0) { country = ianaString.substring(start); } else { country = ianaString.substring(start, dashIndex); variant = ianaString.substring(dashIndex + 1); } } /* * Validate the rules for Locale per its Javadoc: * - The language argument is a valid ISO Language Code. * These codes are the lower-case, two-letter codes as defined by ISO-639. * - The country argument is a valid ISO Country Code. These * codes are the upper-case, two-letter codes as defined by ISO-3166. * * Rather than checking a list, we check the length and case and ignore * the arguments which fail to meet those criteria (use defaults instead). */ if (language.length() != 2) { language = ""; _LOG.warning("INVALID_LOCALE_LANG_LENGTH", ianaString); } else { if (Character.isUpperCase(language.charAt(0)) || Character.isUpperCase(language.charAt(1))) { language = ""; _LOG.warning("INVALID_LOCALE_LANG_CASE", ianaString); } } if (language.length() == 0) { FacesContext fc = FacesContext.getCurrentInstance(); if (fc.getViewRoot() != null) { return (fc.getViewRoot().getLocale()); } else { // ViewRoot may be null, e.g. when TranslationsResourceLoader is called // from the ResourceServlet. // // Cast to a servletRequest here because this should only happen // when run from the Trinidad ResourceServlet. Even in a portlet // environment we should have a servlet request in this circumstance. // If we need to handle getting the locale from portlet objects, we // should add a utility to do so in ExternalContextUtils. ServletRequest req = (ServletRequest) fc.getExternalContext().getRequest(); return (req.getLocale()); } } if (country.length() > 0) { if (country.length() != 2) { country = ""; _LOG.warning("INVALID_LOCALE_COUNTRY_LENGTH", ianaString); } else { if (Character.isLowerCase(country.charAt(0)) || Character.isLowerCase(country.charAt(1))) { country = ""; _LOG.warning("INVALID_LOCALE_COUNTRY_CASE", ianaString); } } } if (variant.indexOf('/') > 0) { // Disallow slashes in the variant to avoid XSS variant = ""; _LOG.warning("INVALID_LOCALE_VARIANT_HAS_SLASH", ianaString); } return new Locale(language, country, variant); } private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(LocaleUtils.class); }
/** * Creates a CollectionModel that is sortable. All properties that implement java.lang.Comparable * are deemed sortable. */ public class SortableModel extends CollectionModel { /** * Create a new SortableModel from the given instance. * * @param model This will be converted into a {@link DataModel} * @see #setWrappedData */ public SortableModel(Object model) { setWrappedData(model); } /** * No arg constructor for use as a managed-bean. Must call setWrappedData before using this * instance. */ public SortableModel() {} @Override public Object getRowData() { return _model.getRowData(); } @Override public Object getWrappedData() { return _wrappedData; } @Override public boolean isRowAvailable() { return _model.isRowAvailable(); } /** * Sets the underlying data being managed by this instance. * * @param data This Object will be converted into a {@link DataModel}. * @see ModelUtils#toDataModel */ @Override public void setWrappedData(Object data) { _baseIndicesList = null; _model = ModelUtils.toDataModel(data); _sortCriterion = null; _sortedIndicesList = null; _wrappedData = data; } @Override public int getRowCount() { return _model.getRowCount(); } @Override public void setRowIndex(int rowIndex) { int baseIndex = _toBaseIndex(rowIndex); _model.setRowIndex(baseIndex); } @Override public int getRowIndex() { int baseIndex = _model.getRowIndex(); return _toSortedIndex(baseIndex); } /** * Gets the row key of the current row * * @inheritDoc */ @Override public Object getRowKey() { return isRowAvailable() ? _model.getRowIndex() : null; } /** * Finds the row with the matching key and makes it current * * @inheritDoc */ @Override public void setRowKey(Object key) { _model.setRowIndex(_toRowIndex(key)); } public void addDataModelListener(DataModelListener listener) { _model.addDataModelListener(listener); } public DataModelListener[] getDataModelListeners() { return _model.getDataModelListeners(); } public void removeDataModelListener(DataModelListener listener) { _model.removeDataModelListener(listener); } /** * Checks to see if the underlying collection is sortable by the given property. * * @param property The name of the property to sort the underlying collection by. * @return true, if the property implements java.lang.Comparable */ @Override public boolean isSortable(String property) { final int oldIndex = _model.getRowIndex(); try { _model.setRowIndex(0); if (!_model.isRowAvailable()) return false; // if there is no data in the table then nothing is sortable Object data = _model.getRowData(); try { // TODO clean up that _getELXyz() calls FacesContext context = FacesContext.getCurrentInstance(); ELResolver resolver = _getELResolver(context); ELContext elContext = _getELContext(context, resolver); Object propertyValue = evaluateProperty(resolver, elContext, data, property); // when the value is null, we don't know if we can sort it. // by default let's support sorting of null values, and let the user // turn off sorting if necessary: return (propertyValue instanceof Comparable) || (propertyValue == null); } catch (RuntimeException e) { // don't propagate this exception out. This is because it might break // the VE. _LOG.warning(e); return false; } } finally { _model.setRowIndex(oldIndex); } } private Object evaluateProperty( ELResolver resolver, ELContext context, Object base, String property) { // simple property -> resolve value directly if (!property.contains(".")) return resolver.getValue(context, base, property); int index = property.indexOf('.'); Object newBase = resolver.getValue(context, base, property.substring(0, index)); return evaluateProperty(resolver, context, newBase, property.substring(index + 1)); } @Override public List<SortCriterion> getSortCriteria() { if (_sortCriterion == null) { return Collections.emptyList(); } else { return Collections.singletonList(_sortCriterion); } } @Override public void setSortCriteria(List<SortCriterion> criteria) { if ((criteria == null) || (criteria.isEmpty())) { _sortCriterion = null; // restore unsorted order: _baseIndicesList = _sortedIndicesList = null; } else { SortCriterion sc = criteria.get(0); if ((_sortCriterion == null) || (!_sortCriterion.equals(sc))) { _sortCriterion = sc; _sort(_sortCriterion.getProperty(), _sortCriterion.isAscending()); } } } @Override public String toString() { return "SortableModel[" + _model + "]"; } /** * Sorts the underlying collection by the given property, in the given direction. * * @param property The name of the property to sort by. The value of this property must implement * java.lang.Comparable. * @param isAscending true if the collection is to be sorted in ascending order. * @todo support -1 for rowCount */ private void _sort(String property, boolean isAscending) { // if (property.equals(_sortBy) && (isAscending == _sortOrder)) // { // return; // } // // _sortBy = property; // _sortOrder = isAscending; // TODO: support -1 for rowCount: int sz = getRowCount(); if ((_baseIndicesList == null) || (_baseIndicesList.size() != sz)) { // we do not want to mutate the original data. // however, instead of copying the data and sorting the copy, // we will create a list of indices into the original data, and // sort the indices. This way, when certain rows are made current // in this Collection, we can make them current in the underlying // DataModel as well. _baseIndicesList = new IntList(sz); } final int rowIndex = _model.getRowIndex(); _model.setRowIndex(0); // Make sure the model has that row 0! (It could be empty.) if (_model.isRowAvailable()) { FacesContext context = FacesContext.getCurrentInstance(); ELResolver resolver = _getELResolver(context); ELContext elContext = _getELContext(context, resolver); Comparator<Integer> comp = new Comp(resolver, elContext, property); if (!isAscending) comp = new Inverter<Integer>(comp); Collections.sort(_baseIndicesList, comp); _sortedIndicesList = null; } _model.setRowIndex(rowIndex); } private int _toSortedIndex(int baseIndex) { if ((_sortedIndicesList == null) && (_baseIndicesList != null)) { _sortedIndicesList = (IntList) _baseIndicesList.clone(); for (int i = 0; i < _baseIndicesList.size(); i++) { Integer base = _baseIndicesList.get(i); _sortedIndicesList.set(base.intValue(), i); } } return _convertIndex(baseIndex, _sortedIndicesList); } private int _toBaseIndex(int sortedIndex) { return _convertIndex(sortedIndex, _baseIndicesList); } private int _convertIndex(int index, List<Integer> indices) { if (index < 0) // -1 is special return index; if ((indices != null) && (indices.size() > index)) { index = indices.get(index).intValue(); } return index; } private int _toRowIndex(Object rowKey) { if (rowKey == null) return -1; try { return ((Integer) rowKey).intValue(); } catch (ClassCastException e) { _LOG.warning("INVALID_ROWKEY", new Object[] {rowKey, rowKey.getClass()}); _LOG.warning(e); return -1; } } private static final class IntList extends ArrayList<Integer> { public IntList(int size) { super(size); _expandToSize(size); } private void _expandToSize(int desiredSize) { for (int i = 0; i < desiredSize; i++) { add(i); } } private static final long serialVersionUID = 1L; } private final class Comp implements Comparator<Integer> { public Comp(ELResolver resolver, ELContext context, String property) { _resolver = resolver; _context = context; _prop = property; } @SuppressWarnings("unchecked") public int compare(Integer o1, Integer o2) { int index1 = o1.intValue(); int index2 = o2.intValue(); _model.setRowIndex(index1); Object instance1 = _model.getRowData(); Object value1 = evaluateProperty(_resolver, _context, instance1, _prop); _model.setRowIndex(index2); Object instance2 = _model.getRowData(); Object value2 = evaluateProperty(_resolver, _context, instance2, _prop); if (value1 == null) return (value2 == null) ? 0 : -1; if (value2 == null) return 1; // bug 4545164. Sometimes, isSortable returns true // even if the underlying object is not a Comparable. // This happens if the object at rowIndex zero is null. // So test before we cast: if (value1 instanceof Comparable) { return ((Comparable<Object>) value1).compareTo(value2); } else { // if the object is not a Comparable, then // the best we can do is string comparison: return value1.toString().compareTo(value2.toString()); } } private final ELResolver _resolver; private final ELContext _context; private final String _prop; } private static final class Inverter<T> implements Comparator<T> { public Inverter(Comparator<T> comp) { _comp = comp; } public int compare(T o1, T o2) { return _comp.compare(o2, o1); } private final Comparator<T> _comp; } /** Quickie implementation of ELContext for use if we're not being called in the JSF lifecycle */ private static final class ELContextImpl extends ELContext { public ELContextImpl(ELResolver resolver) { _resolver = resolver; } @Override public ELResolver getELResolver() { return _resolver; } @Override public FunctionMapper getFunctionMapper() { // Because we're only really being used to pass // to an ELResolver, no FunctionMapper is needed return null; } @Override public VariableMapper getVariableMapper() { // Because we're only really being used to pass // to an ELResolver, no VariableMapper is needed return null; } private final ELResolver _resolver; } static Object __resolveProperty(Object object, String propertyName) { FacesContext context = FacesContext.getCurrentInstance(); ELResolver resolver = _getELResolver(context); ELContext elContext = _getELContext(context, resolver); return resolver.getValue(elContext, object, propertyName); } private static ELContext _getELContext(FacesContext context, ELResolver resolver) { // Hopefully, we have a FacesContext. If not, we're // going to have to synthesize one! if (context != null) return context.getELContext(); return new ELContextImpl(resolver); } private static ELResolver _getELResolver(FacesContext context) { // First try the FacesContext, which is a faster way to // get the ELResolver (and the 99.9% scenario) if (context != null) return context.getApplication().getELResolver(); // If that fails, then we're likely outside of the JSF lifecycle. // Look to the ApplicationFactory. ApplicationFactory factory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); return factory.getApplication().getELResolver(); } private SortCriterion _sortCriterion = null; private DataModel _model = null; private Object _wrappedData = null; private IntList _sortedIndicesList = null, // from baseIndex to sortedIndex _baseIndicesList = null; // from sortedIndex to baseIndex private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(SortableModel.class); }
/** Code specific to a Menu Model's GroupNode. */ public class GroupNode extends MenuNode { /** Constructs a GroupNode */ public GroupNode() { super(); } /** * Called by the Default ActionListener when a menu node is clicked/selected. * * @return String outcome or viewId used during a POST for navigation. */ @Override public String doAction() { // Call the doAction method of my idref node return getRefNode().doAction(); } /** * Get the Destination URL of a page for a GET. * * @return String URL of a page. */ @Override public String getDestination() { // Call the getDestination method of my idref node return getRefNode().getDestination(); } /** * Sets the idref of the node. * * <p>The value of this attribute is an "id" of another node This tells the pointing node where to * obtain its viewId and takes precedence (and will replace) the pointing nodes viewId, if one * exists. This should point to a node of the same style, e.g. actionNode points to actionNode. * * @param idref - String name pointing to the "id" of another node */ public void setIdRef(String idref) { _idref = idref; // Create a list of idref's for easier access if (_idref != null) _makeIdRefList(idref); } /** * Get the node whose id matches this node's idref attribute value. * * @return the MenuNode whose id matches this node's idref attribute value. */ @Override public MenuNode getRefNode() { MenuNode refNode = null; // create one if it does not exist // should not happen, but can't hurt if (_idrefList == null) { String idref = getIdRef(); _makeIdRefList(idref); } // Get idrefList String[] idrefList = _getIdRefList(); // get group node's children List<MenuNode> children = getChildren(); // Traverse the list. Do the following: // o get Node from Model's hashMap of nodes and ids // o check attributes (rendered, disabled, readOnly) // o if they are ok, return the node for (int i = 0; i < Array.getLength(idrefList); i++) { Iterator<MenuNode> childIter = children.iterator(); // All node "id" attribute values had the node's // system hashcode id appended to the id when // placed in the model's idNodeMap. // // Each id in the idreflist of a group node does // NOT have this node sys id appended it to it // and needs to or we won't find the group's // ref node. // // Since group nodes can only point to one of // its children, we iterate through them, get // their sys id and append it to idref until // we find a match (or not). while (childIter.hasNext()) { MenuNode childNode = childIter.next(); String nodeSysId = childNode.getNodeSysId(); // Need to append mode's sys id here to create a // unique id. String refNodeId = idrefList[i] + nodeSysId; refNode = (MenuNode) getRootModel().getNode(refNodeId); // if nothing found, move on to the next child if (refNode != null) break; } if (refNode == null) continue; // Check the attributes of the found node if (!refNode.getRendered() || refNode.getDisabled() || refNode.getReadOnly() || !refNode.getVisible()) { refNode = null; continue; } // Ok, we have a valid RefNode break; } // If no valid node is found, // log an error if (refNode == null) { _LOG.severe("GroupNode " + getLabel() + " refers to no valid node.\n"); return null; } return refNode; } /** * Get the id of the node referred to by the idref attribute of this node. * * @return String id of the node referred to by the idref attribure of this node. */ public String getIdRef() { return _idref; } /* ============================================================= * Private methods * =============================================================*/ /** * _getIdRefList. gets the list of idrefs for this node. * * @return String[] list of idrefs for this node. */ private String[] _getIdRefList() { return _idrefList; } /** * Make a list of idref entries from the nodes String of idref's. * * <p>This should only be called from the node's setIdRef method. So if it is called more than * once (highly unlikely), simply empty out the previous contents. * * @param entries - String of String entries */ private void _makeIdRefList(String entries) { _idrefList = entries.trim().split("\\s+"); } private String _idref = null; private String[] _idrefList = null; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(GroupNode.class); }
/** * Private utility methods for loading source icons. * * @version $Name: $ ($Revision: * adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/image/laf/browser/SourceUtils.java#0 * $) $Date: 10-nov-2005.19:05:11 $ */ class SourceUtils { public static Image getSourceIcon(ImageContext context, Map<Object, Object> properties) { return getSourceIcon(context, properties, ImageConstants.SOURCE_INPUT_STREAM_PROVIDER_KEY); } /** Returns the source Image for the specified requested properties */ public static Image getSourceIcon( ImageContext context, Map<Object, Object> properties, Object key) { InputStreamProvider provider = (InputStreamProvider) properties.get(key); // If we can't get a provider, we can't get an Image if (provider == null) { _log(properties, _PROVIDER_ERROR + " (" + _getKeyName(key) + ")", null); return null; } InputStream in = null; try { in = provider.openInputStream(); } catch (IOException e) { _log(properties, _INPUT_STREAM_ERROR, e); return null; } if (in == null) { _log(properties, _INPUT_STREAM_ERROR, null); return null; } // Note: getImageFromStream() closes up our InputStream, // so we do not explicitly call InputStream.close() here. Image source = ImageUtils.getImageFromStream(in); if (source == null) { _log(properties, _IMAGE_ERROR, null); } return source; } // Logs a warning private static void _log(Map<Object, Object> properties, String message, Throwable t) { if (_LOG.isWarning()) { String source = (String) properties.get(ImageConstants.SOURCE_KEY); if (source != null) message += ("for source icon " + source); _LOG.warning(message, t); } } private static String _getKeyName(Object key) { return key.toString(); } // Error messages private static final String _PROVIDER_ERROR = "Could not get InputStreamProvider"; private static final String _INPUT_STREAM_ERROR = "Could not get InputStream"; private static final String _IMAGE_ERROR = "Could not create image"; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(SourceUtils.class); }
/** * Booolean BoundValue that compares either two BoundValues or a BoundValues and an Object with a * comparison operator and returns the Boolean result. * * <p><STRONG> Only BoundValues that return <CODE>java.lang.Numbers</CODE> or <CODE> * java.lang.Numbers</CODE> can be used with comparisons other than <CODE>COMPARISON_EQUALS</CODE> * and <CODE>COMPARISON_NOT_EQUALS</CODE> </STRONG> * * <p> * * @version $Name: $ ($Revision$) $Date$ * @deprecated This class comes from the old Java 1.2 UIX codebase and should not be used anymore. */ @Deprecated public class ComparisonBoundValue implements BoundValue { /** True if the left and right sides are equivalent. */ public static final int COMPARISON_EQUALS = 1; /** True if the left and right sides are not equivalent. */ public static final int COMPARISON_NOT_EQUALS = ~COMPARISON_EQUALS; /** * True if the left side is greater than the right side. * * <p><STRONG>This requires that both sides be or return <CODE>java.lang.Number</CODE>s. */ public static final int COMPARISON_GREATER_THAN = 2; /** * True if the left side is greater than or equal to the right side. * * <p><STRONG>This requires that both sides be or return <CODE>java.lang.Number</CODE>s. */ public static final int COMPARISON_GREATER_THAN_OR_EQUALS = COMPARISON_GREATER_THAN + COMPARISON_EQUALS; /** * True if the left side is less than the right side. * * <p><STRONG>This requires that both sides be or return <CODE>java.lang.Number</CODE>s. */ public static final int COMPARISON_LESS_THAN = ~COMPARISON_GREATER_THAN_OR_EQUALS; /** * True if the left side is less than or equal to the right side. * * <p><STRONG>This requires that both sides be or return <CODE>java.lang.Number</CODE>s. */ public static final int COMPARISON_LESS_THAN_OR_EQUALS = ~COMPARISON_GREATER_THAN; public ComparisonBoundValue(int comparison, BoundValue leftSideValue, BoundValue rightSideValue) { if (leftSideValue == null) throw new IllegalArgumentException(_LOG.getMessage("NULL_LEFTSIDEVALUE")); if (rightSideValue == null) throw new IllegalArgumentException(_LOG.getMessage("NULL_RIGHTSIDEVALUE")); if ((comparison < COMPARISON_LESS_THAN) || (comparison > COMPARISON_GREATER_THAN_OR_EQUALS)) throw new IllegalArgumentException(_LOG.getMessage("UNKNOWN_COMPARISON")); _comparison = comparison; _leftSideValue = leftSideValue; _rightSideValue = rightSideValue; } public ComparisonBoundValue(int comparison, BoundValue leftSideValue, Object rightSide) { this(comparison, leftSideValue, new FixedBoundValue(rightSide)); } public static ComparisonBoundValue createExistsValue(BoundValue existenceValue) { return new ComparisonBoundValue( COMPARISON_NOT_EQUALS, existenceValue, FixedBoundValue.NULL_VALUE); } /** Calculates the current state of the model. */ public Object getValue(UIXRenderingContext context) { Object leftSide = _leftSideValue.getValue(context); Object rightSide = _rightSideValue.getValue(context); // // determine the comparison to attempt // boolean isNot = false; int comparison = _comparison; // make sure that we can always attempt an equivalence comparison, // by inverting the comparison if necessary if ((comparison & COMPARISON_EQUALS) == 0) { comparison = ~comparison; isNot = true; } boolean areBothNumbers = (leftSide instanceof Number) && (rightSide instanceof Number); boolean newResult; // attempt equivalence comparison if (leftSide == rightSide) { newResult = true; } else if (leftSide != null) { if (areBothNumbers) newResult = _equalsForNumbers((Number) leftSide, (Number) rightSide); else newResult = leftSide.equals(rightSide); } else { newResult = false; } // if we have a greter than / less than comparison and the equivalence // comparison failed, tried the other comparison if (!newResult && (comparison != COMPARISON_EQUALS)) { // numeric comparisons against null always fail if ((leftSide == null) || (rightSide == null)) return Boolean.FALSE; if (!areBothNumbers) { if (_LOG.isSevere()) _LOG.severe(new IllegalArgumentException("Numeric comparisons only allowed on numbers")); return Boolean.FALSE; } Number leftNumber = (Number) leftSide; Number rightNumber = (Number) rightSide; // // at this point the comparison will be either less than or equals // or greater than or equals. Since we know that the equals portion // must have failed, we can simply treat all comparisons as greater // than and invert the result for less than // if (comparison == COMPARISON_LESS_THAN_OR_EQUALS) { isNot = !isNot; } if (leftNumber instanceof Long) { newResult = (leftNumber.longValue() > rightNumber.longValue()); } else { newResult = (leftNumber.doubleValue() > rightNumber.doubleValue()); } } if (isNot) newResult = !newResult; return (newResult) ? Boolean.TRUE : Boolean.FALSE; } private static boolean _equalsForNumbers(Number a, Number b) { if ((a == null) || (b == null)) return (a == b); Class<?> ac = a.getClass(); Class<?> bc = b.getClass(); if (ac == bc) return a.equals(b); if ((ac == Long.class) || (ac == Integer.class) || (ac == Short.class) || (ac == Byte.class)) return _equalsForLong(a.longValue(), b, bc); if ((ac == Double.class) || (ac == Float.class)) return _equalsForDouble(a.doubleValue(), b, bc); if (ac == BigInteger.class) return _equalsForBigInteger((BigInteger) a, b, bc); if (ac == BigDecimal.class) return _equalsForBigDecimal((BigDecimal) a, b, bc); return a.equals(b); } private static boolean _equalsForLong(long a, Number b, Class<?> bc) { if ((bc == Double.class) || (bc == Float.class)) { return (b.doubleValue() == a); } if (bc == BigDecimal.class) { return BigDecimal.valueOf(a).equals(b); } if (bc == BigInteger.class) { return BigInteger.valueOf(a).equals(b); } return a == b.longValue(); } private static boolean _equalsForDouble(double a, Number b, Class<?> bc) { if (bc == BigDecimal.class) { return new BigDecimal(a).equals(b); } if (bc == BigInteger.class) { return new BigDecimal(a).equals(new BigDecimal((BigInteger) b)); } return a == b.doubleValue(); } private static boolean _equalsForBigInteger(BigInteger a, Number b, Class<?> bc) { if (bc == BigDecimal.class) { return new BigDecimal(a).equals(b); } if ((bc == Double.class) || (bc == Float.class)) { return new BigDecimal(a).equals(new BigDecimal(b.doubleValue())); } return BigInteger.valueOf(b.longValue()).equals(a); } private static boolean _equalsForBigDecimal(BigDecimal a, Number b, Class<?> bc) { if (bc == BigInteger.class) { return a.equals(new BigDecimal((BigInteger) b)); } if ((bc == Double.class) || (bc == Float.class)) { return a.equals(new BigDecimal(b.doubleValue())); } return a.equals(BigDecimal.valueOf(b.longValue())); } private BoundValue _leftSideValue; private BoundValue _rightSideValue; private int _comparison; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ComparisonBoundValue.class); }
/** * A resource loader implementation which loads resources for the core renderkit. * * @todo Dynamic version number */ public class CoreRenderKitResourceLoader extends RegexResourceLoader { public CoreRenderKitResourceLoader(ResourceLoader parent) { register("(/.*/Common.*\\.js)", new CoreCommonScriptsResourceLoader(false)); register("(/.*/DebugCommon.*\\.js)", new CoreCommonScriptsResourceLoader(true)); register("(/.*/CoreFmt.*\\.js)", new CoreFormatScriptsResourceLoader(false)); register("(/.*/DebugCoreFmt.*\\.js)", new CoreFormatScriptsResourceLoader(true)); register("(/.*LocaleElements.*\\.js)", new LocaleElementsResourceLoader()); register( "(/.*\\.(css|cur|ico|jpg|gif|png|jpeg|svg|js))", new CoreClassLoaderResourceLoader(parent)); } public static String getLocaleElementsURI(String str, Boolean incVersion) { StringBuffer base = new StringBuffer("/adf/jsLibs/resources/"); base.append(str); base.append("_"); String locStr = getLocale(); base.append(locStr); if (incVersion) base.append(_VERSION); base.append(".js"); return base.toString(); } public static String getLocale() { String path = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()) .getPathInfo(); String locStr = ""; int locIndex = path.indexOf("LocaleElements") + "LocaleElements_".length(); int index = path.indexOf(_VERSION); if (index < 0) index = path.indexOf(".js"); if (index >= 0) locStr = path.substring(locIndex, index); return locStr; } public static String __getVersion() { return _VERSION; } // Path to ResourceServlet // Version string to append to library, style sheet URIs private static final String _VERSION; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(CoreRenderKitResourceLoader.class); static { // Note: Java Package versioning is useless during development when // we have no JARs, whereas this technique works with non-JAR // classpaths as well. String version = "unknown"; try { URL resource = ClassLoaderUtils.getResource("META-INF/trinidad-version.txt"); if (resource != null) { BufferedReader br = null; try { InputStream in = resource.openStream(); br = new BufferedReader(new InputStreamReader(in)); version = br.readLine(); } catch (IOException e) { _LOG.severe(e); } finally { if (br != null) br.close(); } } } catch (IOException e) { _LOG.severe(e); } finally { _VERSION = version; } } }
/** * The includeCompactProperty node is a data structure to store this syntax: border: 1px solid * -tr-property-ref(".AFDarkColor:alias",color); which should resolve to border: 1px solid #cccccc; * (if #cccccc is .AFDarkColor:alias's color. This is similar to includeProperty element, but it is * used on compact css property values. An IncludePropertyNode is a data structure to store this * syntax: color: -tr-property-ref(".AFDarkColor:alias",color); includeProperty element is used to * include a single property of one style within another style. Thus, the includeProperty element is * very similar to the includeStyle element. The only difference is that includeStyle includes all * properties of the referenced style, whereas includeProperty includes only a single property. * * @version $Name: $ ($Revision: * adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/style/xml/parse/IncludeCompactPropertyNode.java#0 * $) $Date: 10-nov-2005.18:58:07 $ */ public class IncludeCompactPropertyNode { /** * Creates an IncludeCompactPropertyNode. If we have border: 1px solid * -tr-property-ref(".AFDarkColor:alias",color); in the css file, then localPropertyName == * border, propertyValues == {"1px solid"}, and includePropertyNodeList will contain the * -tr-property-ref(".AFDarkColor:alias",color); * * @param includePropertyNodeList * @param propertyValues * @param localPropertyName */ public IncludeCompactPropertyNode( String propertyValues, List<IncludePropertyNode> includePropertyNodeList, String localPropertyName) { // The caller of this constructor must have all these values filled out. if (propertyValues == null) throw new IllegalArgumentException(); if (includePropertyNodeList == null) throw new IllegalArgumentException(); if (localPropertyName == null) throw new IllegalArgumentException(); _propertyValues = propertyValues; _includePropertyNodeList = includePropertyNodeList; _localPropertyName = localPropertyName; } /** Returns the name of the style to include. */ public String getLocalPropertyName() { return _localPropertyName; } /** Returns the name of the style to include. */ public String getPropertyValues() { return _propertyValues; } public Collection<IncludePropertyNode> getIncludedProperties() { return _includePropertyNodeList; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof IncludeCompactPropertyNode)) return false; // obj at this point must be an IncludeCompactPropertyNode IncludeCompactPropertyNode test = (IncludeCompactPropertyNode) obj; return (_localPropertyName == test._localPropertyName || (_localPropertyName != null && _localPropertyName.equals(test._localPropertyName))) && (_propertyValues == test._propertyValues || (_propertyValues != null && _propertyValues.equals(test._propertyValues))) && (_includePropertyNodeList == test._includePropertyNodeList || (_includePropertyNodeList != null && _includePropertyNodeList.equals(test._includePropertyNodeList))); } @Override public int hashCode() { int hash = 17; hash = 37 * hash + ((null == _localPropertyName) ? 0 : _localPropertyName.hashCode()); hash = 37 * hash + ((null == _propertyValues) ? 0 : _propertyValues.hashCode()); hash = 37 * hash + ((null == _includePropertyNodeList) ? 0 : _includePropertyNodeList.hashCode()); return hash; } @Override // TODO jmwOctober. test this public String toString() { return "[propertyValues=" + _propertyValues + ", " + "includePropertyNodeList=" + _includePropertyNodeList + "]"; } private final String _propertyValues; private final List<IncludePropertyNode> _includePropertyNodeList; private final String _localPropertyName; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(IncludeCompactPropertyNode.class); }
/** Renderer for process train components */ public class TrainRenderer extends XhtmlRenderer { /** Constructor. */ public TrainRenderer() { super(CoreTrain.TYPE); } /** */ @SuppressWarnings("unchecked") @Override public void decode(FacesContext context, UIComponent component) { Map<String, String> requestMap = context.getExternalContext().getRequestParameterMap(); Object event = requestMap.get(XhtmlConstants.EVENT_PARAM); if ((event != null) && event.equals(XhtmlConstants.GOTO_EVENT)) { Object source = requestMap.get(XhtmlConstants.SOURCE_PARAM); if (source != null && source.equals(component.getClientId(context))) { Object valueObject = requestMap.get(XhtmlConstants.VALUE_PARAM); // we piggyback on the size parameter. // 0 means we are moving to a previous step, 1 means we are // moving to the next step. Object sizeObject = requestMap.get(XhtmlConstants.SIZE_PARAM); if (valueObject != null) { int value = -1; try { value = Integer.parseInt(valueObject.toString()); } catch (NumberFormatException nfe) { _LOG.severe(nfe); } int size = 0; try { size = Integer.parseInt(sizeObject.toString()); } catch (NumberFormatException nfe) { _LOG.warning(nfe); } if (size < 0) size = 0; if (value >= 0) { UIXProcess process = (UIXProcess) component; Object oldPath = process.getRowKey(); Object focusPath = process.getFocusRowKey(); process.setRowKey(focusPath); UIComponent stamp = process.getNodeStamp(); int index = process.getRowIndex(); if (size == 0) { index = ProcessUtils.getBackIndex(process, stamp, index); } else { index = ProcessUtils.getNextIndex(process, stamp, index); } process.setRowIndex(index); new ActionEvent(stamp).queue(); process.setRowKey(oldPath); } } } } } /** @return */ @Override public boolean getRendersChildren() { return true; } @Override protected void encodeAll( FacesContext context, RenderingContext arc, UIComponent component, FacesBean bean) throws IOException { // Since Train is a naming container, we can be more // efficient about skipping its children if (!PartialPageUtils.containsPprTargets(arc, component, getClientId(context, component))) { return; } if (!(component instanceof UIXProcess)) { throw new ClassCastException( _LOG.getMessage( "TRAINRENDERER_ONLY_RENDERS_INSTANCE", new Object[] {UIXProcess.class.getName(), component.getClass().getName()})); } if (arc.getFormData() == null) { _LOG.warning("TRAIN_MUST_INSIDE_FORM"); return; } UIXProcess process = (UIXProcess) component; UIComponent stamp = process.getNodeStamp(); if (stamp != null) { Train train = new Train(context, arc, process, stamp); try { process.setRowKey(train.getFocusRowKey()); // Renders some fields and scripts _renderHiddenFields(context, arc, train); ResponseWriter writer = context.getResponseWriter(); // Need to render the frame even if there's no visible station // to support PPR. writer.startElement(XhtmlConstants.TABLE_ELEMENT, component); process.setRowKey(train.getInitialRowKey()); renderId(context, component); renderAllAttributes(context, arc, bean); // Does not seem to be needed and this is not XHTML 1.0 Strict compliant // writer.writeAttribute("align", "center", null); if (!train.getStations().isEmpty()) { process.setRowKey(train.getFocusRowKey()); // There're visible stations currently, let render them. writer.startElement(XhtmlConstants.TABLE_BODY_ELEMENT, null); _renderTrain(context, arc, process, bean, stamp, train); writer.endElement(XhtmlConstants.TABLE_BODY_ELEMENT); } writer.endElement(XhtmlConstants.TABLE_ELEMENT); } finally { // Always restore the model, whatever happened process.setRowKey(train.getInitialRowKey()); } } else { _LOG.warning("NODESTAMP_FACET_NOT_FOUND_FOR_TRAIN", component); } /* _encodeChildren(context, arc, process, stamp, trainState, length); */ } @Override protected void renderAllAttributes(FacesContext context, RenderingContext arc, FacesBean bean) throws IOException { super.renderAllAttributes(context, arc, bean); OutputUtils.renderLayoutTableAttributes(context, arc, "0", null); } /** This is how we can render both the user defined styleClass and our component style class */ @Override protected void renderStyleAttributes(FacesContext context, RenderingContext arc, FacesBean bean) throws IOException { renderStyleAttributes(context, arc, bean, SkinSelectors.AF_TRAIN_ROOT_STYLE_CLASS); } private void _preRenderIconBlock(FacesContext context, RenderingContext arc) throws IOException { ResponseWriter writer = context.getResponseWriter(); // Icon cell writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null); // Icons need to be in a table to stretch well writer.startElement(XhtmlConstants.TABLE_ELEMENT, null); OutputUtils.renderLayoutTableAttributes(context, arc, "0", null); writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE, "width: 100%", null); writer.startElement(XhtmlConstants.TABLE_BODY_ELEMENT, null); writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null); } private void _postRenderIconBlock(FacesContext context) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT); writer.endElement(XhtmlConstants.TABLE_BODY_ELEMENT); writer.endElement(XhtmlConstants.TABLE_ELEMENT); writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT); } private void _renderHiddenFields(FacesContext context, RenderingContext arc, Train train) throws IOException { if ((train.getFormName() != null) && supportsScripting(arc)) { // render hidden fields to hold the form data FormData formData = arc.getFormData(); if (formData != null) { formData.addNeededValue(XhtmlConstants.EVENT_PARAM); formData.addNeededValue(XhtmlConstants.SOURCE_PARAM); formData.addNeededValue(XhtmlConstants.VALUE_PARAM); formData.addNeededValue(XhtmlConstants.SIZE_PARAM); } // Render script submission code. ProcessUtils.renderNavSubmitScript(context, arc); } } private void _renderContentRowLtr( FacesContext context, RenderingContext arc, UIXProcess process, UIComponent stamp, Train train) throws IOException { ParentTrain parentTrain = train.getParentTrain(); // Render parent start if (parentTrain != null && parentTrain.hasParentStart()) { _renderParentContent(context, arc, parentTrain.getParentStart()); } for (Station station : train.getStations()) { _renderStationContent(context, arc, process, stamp, station); } // Render parent end if (parentTrain != null && parentTrain.hasParentEnd()) { _renderParentContent(context, arc, parentTrain.getParentEnd()); } } private void _renderContentRowRtl( FacesContext context, RenderingContext arc, UIXProcess process, UIComponent stamp, Train train) throws IOException { ParentTrain parentTrain = train.getParentTrain(); // Render parent start if (parentTrain != null && parentTrain.hasParentEnd()) { _renderParentContent(context, arc, parentTrain.getParentEnd()); } List<Station> stations = train.getStations(); ListIterator<Station> iterator = stations.listIterator(stations.size()); while (iterator.hasPrevious()) { _renderStationContent(context, arc, process, stamp, iterator.previous()); } // Render parent end if (parentTrain != null && parentTrain.hasParentStart()) { _renderParentContent(context, arc, parentTrain.getParentStart()); } } private void _renderIconBlock( FacesContext context, RenderingContext arc, List<String> iconNames, String shortDesc, String styleClass, String iconStyleClass, List<String> stateStyleClasses) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null); stateStyleClasses.add(styleClass); stateStyleClasses.add(iconStyleClass); renderStyleClasses(context, arc, stateStyleClasses.toArray(_EMPTY_STRING_ARRAY)); if (iconNames != null) { // Render the first valid icon found. The list should be in // decreasing priority order. for (String iconName : iconNames) { Icon icon = arc.getIcon(iconName); if (icon != null) { OutputUtils.renderIcon(context, arc, icon, shortDesc, null); break; } } } writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT); } private void _renderIconRowLtr( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { ParentTrain parentTrain = train.getParentTrain(); // Render parent start if (parentTrain != null && parentTrain.hasParentStart()) { _renderParentStartLtr(context, arc, process, train); } for (Station station : train.getStations()) { _renderStationIconLtr(context, arc, process, station); } // Render parent end if (parentTrain != null && parentTrain.hasParentEnd()) { _renderParentEndLtr(context, arc, process, train); } } private void _renderIconRowRtl( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { ParentTrain parentTrain = train.getParentTrain(); // Render parent end if (parentTrain != null && parentTrain.hasParentEnd()) { _renderParentEndRtl(context, arc, process, train); } List<Station> stations = train.getStations(); ListIterator<Station> iterator = stations.listIterator(stations.size()); while (iterator.hasPrevious()) { _renderStationIconRtl(context, arc, process, iterator.previous()); } // Render parent start if (parentTrain != null && parentTrain.hasParentStart()) { _renderParentStartRtl(context, arc, process, train); } } private void _renderJoin( FacesContext context, RenderingContext arc, String stateStyleClass, boolean overflow) throws IOException { if (_STATE_PARENT.equals(stateStyleClass)) { _renderJoin(context, arc, SkinSelectors.AF_TRAIN_PARENT_JOIN_STYLE_CLASS, null); } else if (overflow) { _renderJoin(context, arc, SkinSelectors.AF_TRAIN_OVERFLOW_JOIN_STYLE_CLASS, stateStyleClass); } else { _renderJoin(context, arc, SkinSelectors.AF_TRAIN_JOIN_STYLE_CLASS, stateStyleClass); } } private void _renderJoin( FacesContext context, RenderingContext arc, String joinStyleClass, String stateStyleClass) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null); renderStyleClasses(context, arc, new String[] {joinStyleClass, stateStyleClass}); writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT); } private void _renderJoinIconBlock( FacesContext context, RenderingContext arc, String stateStyleClass, boolean overflow) throws IOException { if (_STATE_PARENT.equals(stateStyleClass)) { _renderJoinIconBlock(context, arc, SkinSelectors.AF_TRAIN_PARENT_JOIN_STYLE_CLASS, null); } else if (overflow) { _renderJoinIconBlock( context, arc, SkinSelectors.AF_TRAIN_OVERFLOW_JOIN_STYLE_CLASS, stateStyleClass); } else { _renderJoinIconBlock(context, arc, SkinSelectors.AF_TRAIN_JOIN_STYLE_CLASS, stateStyleClass); } } private void _renderJoinIconBlock( FacesContext context, RenderingContext arc, String joinStyleClass, String stateStyleClass) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null); writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE, "width: 50%", null); renderStyleClasses(context, arc, new String[] {joinStyleClass, stateStyleClass}); writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT); } private void _renderParentContent(FacesContext context, RenderingContext arc, Station parent) throws IOException { ResponseWriter writer = context.getResponseWriter(); String baseStyleClass = parent.getBaseStyleClass(); writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null); writer.writeAttribute(XhtmlConstants.COLSPAN_ATTRIBUTE, "3", null); renderStyleClasses( context, arc, new String[] {baseStyleClass, baseStyleClass + _SUFFIX_CONTENT}); /* -= Simon =- * FIXME HACK for MSIE CSS bug involving composite style classes. * Since the bug is most obvious with join background images * I hard code background-image to none to fix it. * See Jira for issue ADFFACES-206. */ if (arc.getAgent().getAgentName().equalsIgnoreCase(Agent.AGENT_IE)) { writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE, "background-image:none;", null); } writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT); } private void _renderParentEnd( FacesContext context, RenderingContext arc, UIXProcess process, Train train, String leftState, String rightState) throws IOException { // Add join _renderJoin(context, arc, leftState, false); // Icon cell _preRenderIconBlock(context, arc); // Add join _renderJoinIconBlock(context, arc, leftState, false); // Add the parent's stop icon _renderParentEndIconBlock(context, arc, process, train); // Add join _renderJoinIconBlock(context, arc, rightState, false); // End icon cell _postRenderIconBlock(context); // Add join _renderJoin(context, arc, rightState, false); } private void _renderParentEndLtr( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { _renderParentEnd(context, arc, process, train, _STATE_PARENT, null); } private void _renderParentEndRtl( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { _renderParentEnd(context, arc, process, train, null, _STATE_PARENT); } private void _renderParentEndIconBlock( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { assert train.getParentTrain().hasParentEnd(); Station parent = train.getParentTrain().getParentEnd(); process.setRowKey(parent.getRowKey()); _renderStationIconBlock(context, arc, process, parent); // Restore model process.setRowKey(train.getInitialRowKey()); } private void _renderParentStartIconBlock( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { assert train.getParentTrain().hasParentStart(); Station parent = train.getParentTrain().getParentStart(); process.setRowKey(parent.getRowKey()); _renderStationIconBlock(context, arc, process, parent); // Restore model process.setRowKey(train.getInitialRowKey()); } private void _renderParentStart( FacesContext context, RenderingContext arc, UIXProcess process, Train train, String leftState, String rightState) throws IOException { // Add join _renderJoin(context, arc, leftState, false); // Icon cell _preRenderIconBlock(context, arc); // Add join _renderJoinIconBlock(context, arc, leftState, false); // Add the parent's stop icon _renderParentStartIconBlock(context, arc, process, train); // Add join _renderJoinIconBlock(context, arc, rightState, false); _postRenderIconBlock(context); // End icon cell // Add join _renderJoin(context, arc, rightState, false); } private void _renderParentStartLtr( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { _renderParentStart(context, arc, process, train, null, _STATE_PARENT); } private void _renderParentStartRtl( FacesContext context, RenderingContext arc, UIXProcess process, Train train) throws IOException { _renderParentStart(context, arc, process, train, _STATE_PARENT, null); } private void _renderStationContent( FacesContext context, RenderingContext arc, UIXProcess process, UIComponent stamp, Station station) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null); writer.writeAttribute(XhtmlConstants.COLSPAN_ATTRIBUTE, "3", null); String baseStyleClass = station.getBaseStyleClass(); List<String> stateStyleClasses = station.getStates(); stateStyleClasses.add(baseStyleClass); stateStyleClasses.add(baseStyleClass + _SUFFIX_CONTENT); renderStyleClasses(context, arc, stateStyleClasses.toArray(_EMPTY_STRING_ARRAY)); /* -= Simon =- * FIXME HACK for MSIE CSS bug involving composite style classes. * Since the bug is most obvious with join background images * I hard code background-image to none to fix it. * See Jira for issue ADFFACES-206. */ if (arc.getAgent().getAgentName().equalsIgnoreCase(Agent.AGENT_IE)) { writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE, "background-image:none;", null); } Map<String, String> originalMap = arc.getSkinResourceKeyMap(); // Init the model process.setRowIndex(station.getRowIndex()); try { arc.setSkinResourceKeyMap(_RESOURCE_KEY_MAP); encodeChild(context, stamp); } finally { arc.setSkinResourceKeyMap(originalMap); } writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT); } private void _renderStationIcon( FacesContext context, RenderingContext arc, UIXProcess process, Station station, String leftJoinState, String rightJoinState, boolean overflowLeft, boolean overflowRight) throws IOException { // Add join _renderJoin(context, arc, leftJoinState, overflowLeft); // Icon cell _preRenderIconBlock(context, arc); // Add join _renderJoinIconBlock(context, arc, leftJoinState, overflowLeft); // Add the parent's stop icon _renderStationIconBlock(context, arc, process, station); // Add join _renderJoinIconBlock(context, arc, rightJoinState, overflowRight); // End icon cell _postRenderIconBlock(context); // Add join _renderJoin(context, arc, rightJoinState, overflowRight); } private void _renderStationIconBlock( FacesContext context, RenderingContext arc, UIXProcess process, Station station) throws IOException { process.setRowIndex(station.getRowIndex()); String baseStyleClass = station.getBaseStyleClass(); _renderIconBlock( context, arc, station.getIconNames(), station.getLabel(), baseStyleClass, baseStyleClass + _SUFFIX_ICON_CELL, station.getStates()); } private void _renderStationIconLtr( FacesContext context, RenderingContext arc, UIXProcess process, Station station) throws IOException { _renderStationIcon( context, arc, process, station, station.getStartJoinState(), station.getEndJoinState(), station.hasPrevious() && station.getPrevious().isOverflowStart(), station.hasNext() && station.getNext().isOverflowEnd()); } private void _renderStationIconRtl( FacesContext context, RenderingContext arc, UIXProcess process, Station station) throws IOException { _renderStationIcon( context, arc, process, station, station.getEndJoinState(), station.getStartJoinState(), station.hasNext() && station.getNext().isOverflowEnd(), station.hasPrevious() && station.getPrevious().isOverflowStart()); } private void _renderTrain( FacesContext context, RenderingContext arc, UIXProcess process, FacesBean bean, UIComponent stamp, Train train) throws IOException { ResponseWriter writer = context.getResponseWriter(); // Start of the icon row writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null); if (arc.isRightToLeft()) { _renderIconRowRtl(context, arc, process, train); } else { _renderIconRowLtr(context, arc, process, train); } writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT); // Start of the content row writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null); if (arc.isRightToLeft()) { _renderContentRowRtl(context, arc, process, stamp, train); } else { _renderContentRowLtr(context, arc, process, stamp, train); } writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT); } private static class Train { public Train( FacesContext context, RenderingContext arc, UIXProcess process, UIComponent stamp) { // Save the model state int activeIndex = _loadStations(process, stamp); int visibleStopCount = _getVisibleStopCount(arc); _formName = arc.getFormData().getName(); _isSubTrain = _loadIsSubTrain(process); if (!_stations.isEmpty()) { // There's something visible in the train if (_stations.size() > visibleStopCount) { // We have overflow, let resolve it _resolveOverflow(visibleStopCount, activeIndex); } else { // No overflow, yay! _resolveStandard(); } _initLabels(arc, process, stamp); _initParentTrain(arc, process, stamp); } } public Object getFocusRowKey() { return _focusRowKey; } public String getFormName() { return _formName; } public Object getInitialRowKey() { return _initialRowKey; } public ParentTrain getParentTrain() { return _parent; } public List<Station> getStations() { return _stations; } public boolean isSubTrain() { return _isSubTrain; } private void _createStation(UIXProcess process, UIComponent stamp, int index, boolean active) { process.setRowIndex(index); if (stamp.isRendered()) { // The station will be visible. _stations.add(new Station(this, stamp, index, process.getRowKey(), active)); } } private int _getVisibleStopCount(RenderingContext arc) { Object propValue = arc.getSkin().getProperty(SkinProperties.AF_TRAIN_VISIBLE_STOP_COUNT); if (propValue == null) { return DEFAULT_MAX_VISIBLE_STOP_COUNT; } try { int count = Integer.parseInt(propValue.toString()); if (count <= 0) { _LOG.warning("VISIBLE_STOP_COUNT_MUST_ABOVE_ZERO", count); return DEFAULT_MAX_VISIBLE_STOP_COUNT; } return count; } catch (NumberFormatException e) { _LOG.warning("VISIBLE_STOP_COUNT_MYST_INTEGER", propValue); return DEFAULT_MAX_VISIBLE_STOP_COUNT; } } private void _initLabels(RenderingContext arc, UIXProcess process, UIComponent stamp) { for (Station s : _stations) { process.setRowIndex(s.getRowIndex()); s.initLabel(arc, stamp); } } private void _initParentTrain(RenderingContext arc, UIXProcess process, UIComponent stamp) { if (_isSubTrain) { if (_shouldRenderParentTrain(arc)) { _parent = new ParentTrain(arc, process, stamp, this); if (!_parent.hasParentStart() && !_parent.hasParentEnd()) { _isSubTrain = false; } } else { _isSubTrain = false; } } } /** Determine if this train is a sub-train. */ private boolean _loadIsSubTrain(UIXProcess process) { Object focusRowKey = process.getFocusRowKey(); if (focusRowKey != null && (process.getDepth(focusRowKey) > 0)) { return true; } return false; } private int _loadStations(UIXProcess process, UIComponent stamp) { _initialRowKey = process.getRowKey(); try { // Set the model on the focus item _focusRowKey = process.getFocusRowKey(); process.setRowKey(_focusRowKey); int count = process.getRowCount(); int activeIndex = process.getRowIndex(); int index = 0; assert activeIndex < count; _stations = new ArrayList<Station>(count); boolean bActiveStop = false; // Process visited stations for (; index < count; index++) { bActiveStop = (index == activeIndex); _createStation(process, stamp, index, bActiveStop); if (bActiveStop) { // Might have an invisible active station. Thsi is weird, but still. // You never know what users want to do, but let support // it nevertheless for now. // selectedIndex is either the active station index or the index // of the station just before the selected one if active is not visible. activeIndex = _stations.size() - 1; } } return activeIndex; } finally { // Restore the model's state process.setRowKey(_initialRowKey); } } private void _resolveOverflow(int visibleStopCount, int activeIndex) { assert _stations != null; assert activeIndex >= -1; assert activeIndex < _stations.size(); // First, resolve chaining _resolveStandard(); // We have more stations than the max available, so we have an overflow // for sure. if (activeIndex <= 0) { // Overflow to the following group only _resolveOverflowEnd(visibleStopCount); _stations = _stations.subList(0, visibleStopCount + 1); } else { // Get the visible group index int groupIndex = activeIndex / visibleStopCount; int startIndex = 0; int endIndex = _stations.size(); if (groupIndex > 0) { // We have a previous overflow startIndex = groupIndex * visibleStopCount - 1; _resolveOverflowStart(startIndex); } int maxGroupIndex = (_stations.size() - 1) / visibleStopCount; if (groupIndex < maxGroupIndex) { // We have a next overflow int overflowIndex = (groupIndex + 1) * visibleStopCount; // endIndex is exclusive endIndex = overflowIndex + 1; _resolveOverflowEnd(overflowIndex); } _stations = _stations.subList(startIndex, endIndex); } } private void _resolveOverflowEnd(int index) { assert _stations != null; assert index >= 0; assert index < _stations.size(); Station station = _stations.get(index); station.setOverflowEnd(true); if (station.hasPrevious() && station.getPrevious().isDisabled()) { // If previous stop is disabled, so is the overflow station.setDisabled(true); } station.setNext(null); } private void _resolveOverflowStart(int index) { assert _stations != null; assert index >= 0; assert index < _stations.size(); Station station = _stations.get(index); station.setOverflowStart(true); if (station.hasNext() && station.getNext().isDisabled()) { // If next stop is disabled, so is the overflow station.setDisabled(true); } station.setPrevious(null); } private void _resolveStandard() { if (_stations.size() > 1) { Iterator<Station> iterator = _stations.iterator(); Station previous = null; Station current = iterator.next(); Station next = iterator.next(); _updateStation(current, previous, next); while (iterator.hasNext()) { previous = current; current = next; next = iterator.next(); _updateStation(current, previous, next); } next.setPrevious(current); } } private boolean _shouldRenderParentTrain(RenderingContext arc) { Object propValue = arc.getSkin().getProperty(SkinProperties.AF_TRAIN_RENDER_PARENT_TRAIN); if (propValue == null) { return DEFAULT_RENDER_PARENT_TRAIN; } return Boolean.TRUE.equals(propValue); } private void _updateStation(Station current, Station previous, Station next) { current.setPrevious(previous); current.setNext(next); } private Object _focusRowKey; private String _formName; private Object _initialRowKey; private boolean _isSubTrain; private ParentTrain _parent; private List<Station> _stations; } private static class Station { public Station(Train train, int index, Object rowKey) { _rowIndex = index; _rowKey = rowKey; _active = false; _visited = false; _disabled = false; _parentEnd = false; _parentStart = false; _train = train; } @SuppressWarnings("unchecked") public Station(Train train, UIComponent stamp, int index, Object rowKey, boolean active) { Map<String, Object> attributes = stamp.getAttributes(); _rowIndex = index; _rowKey = rowKey; _active = active; _selected = _getBooleanAttribute(attributes, "selected", false); _visited = _getBooleanAttribute(attributes, "visited", false); _disabled = _getBooleanAttribute(attributes, "disabled", false); _parentEnd = false; _parentStart = false; _train = train; } public String getBaseStyleClass() { if (isOverflowEnd()) { return SkinSelectors.AF_TRAIN_OVERFLOW_END_STYLE_CLASS; } else if (isOverflowStart()) { return SkinSelectors.AF_TRAIN_OVERFLOW_START_STYLE_CLASS; } else if (isParentStart()) { return SkinSelectors.AF_TRAIN_PARENT_START_STYLE_CLASS; } else if (isParentEnd()) { return SkinSelectors.AF_TRAIN_PARENT_END_STYLE_CLASS; } else { return SkinSelectors.AF_TRAIN_STOP_STYLE_CLASS; } } public String getEndJoinState() { if (isOverflowEnd()) { return null; } else if (!hasNext()) { ParentTrain parent = _train.getParentTrain(); if (parent != null && parent.hasParentEnd()) { return _STATE_PARENT; } else { return null; } } else if (getNext().isVisited()) { return _STATE_VISITED; } else { if (getNext().isDisabled()) { return _STATE_DISABLED; } return _STATE_UNVISITED; } } public List<String> getIconNames() { if (isOverflowEnd()) { return _getOverflowEndIconNames(); } else if (isOverflowStart()) { return _getOverflowStartIconNames(); } else if (isParentStart()) { return Collections.singletonList(SkinSelectors.AF_TRAIN_PARENT_START_ICON_NAME); } else if (isParentEnd()) { return Collections.singletonList(SkinSelectors.AF_TRAIN_PARENT_END_ICON_NAME); } else { return _getStopIconNames(); } } public String getLabel() { return _label; } public Station getNext() { return _next; } public Station getPrevious() { return _previous; } public int getRowIndex() { return _rowIndex; } public Object getRowKey() { return _rowKey; } public String getStartJoinState() { if (isOverflowStart()) { return null; } else if (!hasPrevious()) { ParentTrain parent = _train.getParentTrain(); if (parent != null && parent.hasParentStart()) { return _STATE_PARENT; } else { return null; } } else if (isVisited()) { return _STATE_VISITED; } else { if (isDisabled()) { return _STATE_DISABLED; } return _STATE_UNVISITED; } } public List<String> getStates() { List<String> states = new ArrayList<String>(5); if (isParentStart() || isParentEnd()) { return states; } if (isActive() || isSelected()) { states.add(_STATE_ACTIVE); return states; } else if (isVisited()) { states.add(_STATE_VISITED); } else { states.add(_STATE_UNVISITED); } if (isDisabled()) { states.add(_STATE_READ_ONLY); } return states; } public boolean hasNext() { return _next != null; } public boolean hasPrevious() { return _previous != null; } /** * return the string to use for the text of the station it is the text of the link or "Previous" * or "More" */ public void initLabel(RenderingContext arc, UIComponent stamp) { if (isOverflowStart()) { _label = arc.getTranslatedString(_PREVIOUS_KEY); } else if (isOverflowEnd()) { _label = arc.getTranslatedString(_MORE_KEY); } else { Object text = stamp.getAttributes().get("text"); if (text != null) { _label = text.toString(); if (isScreenReaderMode(arc)) { _label = _getDisabledUserText(arc, _label); } } else { _label = null; } } } public boolean isActive() { return _active; } public boolean isSelected() { return _selected; } public boolean isDisabled() { return _disabled; } public boolean isNextDisabled() { return hasNext() && _next.isDisabled(); } public boolean isOverflowEnd() { return _overflowEnd; } public boolean isOverflowStart() { return _overflowStart; } public boolean isParentEnd() { return _parentEnd; } public boolean isParentStart() { return _parentStart; } public boolean isPreviousDisabled() { return hasPrevious() && _previous.isDisabled(); } public boolean isVisited() { return _visited; } public void setDisabled(boolean disabled) { _disabled = disabled; } public void setNext(Station next) { _next = next; } public void setOverflowEnd(boolean overflowEnd) { _overflowEnd = overflowEnd; } public void setOverflowStart(boolean overflowStart) { _overflowStart = overflowStart; _visited = true; } public void setParentEnd(boolean parentEnd) { _parentEnd = parentEnd; } public void setParentStart(boolean parentStart) { _parentStart = parentStart; } public void setPrevious(Station previous) { _previous = previous; } private boolean _getBooleanAttribute( Map<String, Object> attributes, String attributeName, boolean defaultValue) { Object value = attributes.get(attributeName); if (value == null) { return defaultValue; } return Boolean.TRUE.equals(value); } private String _getDisabledUserText(RenderingContext arc, String text) { String altTextKey; if (isActive() || isSelected()) { altTextKey = _ACTIVE_KEY; } else if (isVisited()) { altTextKey = _VISITED_KEY; } else { altTextKey = _NEXT_KEY; } String altText = XhtmlUtils.getFormattedString(arc.getTranslatedString(altTextKey), new String[] {text}); return altText; } private List<String> _getIconNames(String baseSelector) { LinkedList<String> names = new LinkedList<String>(); StringBuilder builder = new StringBuilder(64); builder.append(baseSelector); int suffixLength = SkinSelectors.ICON_SUFFIX.length(); int baseIndex = builder.length(); builder.append(SkinSelectors.ICON_SUFFIX); names.addFirst(builder.toString()); builder.delete(baseIndex, baseIndex + suffixLength); if (isActive() || isSelected()) { builder.append(_SUFFIX_ACTIVE); } else if (isVisited()) { builder.append(_SUFFIX_VISITED); } else { builder.append(_SUFFIX_UNVISITED); } baseIndex = builder.length(); builder.append(SkinSelectors.ICON_SUFFIX); names.addFirst(builder.toString()); builder.delete(baseIndex, baseIndex + suffixLength); if (isDisabled()) { builder.append(_SUFFIX_READ_ONLY); builder.append(SkinSelectors.ICON_SUFFIX); names.addFirst(builder.toString()); } return names; } private List<String> _getOverflowEndIconNames() { return _getIconNames(SkinSelectors.AF_TRAIN_OVERFLOW_END_STYLE_CLASS); } private List<String> _getOverflowStartIconNames() { return _getIconNames(SkinSelectors.AF_TRAIN_OVERFLOW_START_STYLE_CLASS); } private List<String> _getStopIconNames() { return _getIconNames(SkinSelectors.AF_TRAIN_STOP_STYLE_CLASS); } private boolean _active; // Is this station the active one? private boolean _selected; // Is this station the selected one? private boolean _disabled; // Disabled attribute private boolean _overflowEnd; // Is this station the next step set link? private boolean _overflowStart; // Is this station the prev step set link? private boolean _parentEnd; // Is this station a parent end? private boolean _parentStart; // Is this station a parent start? private boolean _visited; // visited attribute private int _rowIndex; // Row index private Object _rowKey; // Row key private String _label; // This station's label private Station _next; private Station _previous; private Train _train; } private static class ParentTrain { public ParentTrain(RenderingContext arc, UIXProcess process, UIComponent stamp, Train train) { List<Station> stations = train.getStations(); int stationCount = stations.size(); boolean hasParentStart = !stations.get(0).isOverflowStart(); boolean hasParentEnd = !stations.get(stationCount - 1).isOverflowEnd(); if (hasParentStart || hasParentEnd) { Object parentStartRowKey = process.getContainerRowKey(); process.setRowKey(parentStartRowKey); int rowIndex = process.getRowIndex(); if (hasParentStart) { _parentStart = new Station(train, rowIndex, parentStartRowKey); _parentStart.setParentStart(true); _parentStart.initLabel(arc, stamp); } rowIndex = rowIndex + 1; // Check if the parent has more steps, render it only if it does hasParentEnd = rowIndex < process.getRowCount(); if (hasParentEnd) { process.setRowIndex(rowIndex); _parentEnd = new Station(train, rowIndex, process.getRowKey()); _parentEnd.setParentEnd(true); _parentEnd.initLabel(arc, stamp); } // Restore the model process.setRowKey(train.getInitialRowKey()); } } public Station getParentEnd() { return _parentEnd; } public Station getParentStart() { return _parentStart; } public boolean hasParentEnd() { return _parentEnd != null; } public boolean hasParentStart() { return _parentStart != null; } private Station _parentEnd; private Station _parentStart; } /** * Gives the amount of visible stops that get rendered by default if no amount is specified by the * -tr-visible-stop-count skin property. */ public static final int DEFAULT_MAX_VISIBLE_STOP_COUNT = 6; /** * Determines if the parent train of sub-trains should be rendered by default if not specified by * the -tr-render-parent-train skin property. */ public static final boolean DEFAULT_RENDER_PARENT_TRAIN = false; private static final String _STATE_ACTIVE = SkinSelectors.STATE_PREFIX + "Selected"; private static final String _STATE_DISABLED = SkinSelectors.STATE_PREFIX + "Disabled"; private static final String _STATE_PARENT = SkinSelectors.STATE_PREFIX + "Parent"; private static final String _STATE_READ_ONLY = SkinSelectors.STATE_PREFIX + "ReadOnly"; private static final String _STATE_UNVISITED = SkinSelectors.STATE_PREFIX + "Unvisited"; private static final String _STATE_VISITED = SkinSelectors.STATE_PREFIX + "Visited"; private static final String _SUFFIX_CONTENT = "-content"; private static final String _SUFFIX_ICON_CELL = "-icon-cell"; private static final String _SUFFIX_ACTIVE = ":selected"; private static final String _SUFFIX_READ_ONLY = ":read-only"; private static final String _SUFFIX_UNVISITED = ":unvisited"; private static final String _SUFFIX_VISITED = ":visited"; /** The following keys are used to get at the corresponding translated strings. */ private static final String _VISITED_KEY = "af_train.VISITED_TIP"; private static final String _ACTIVE_KEY = "af_train.ACTIVE_TIP"; private static final String _NEXT_KEY = "af_train.NEXT_TIP"; private static final String _MORE_KEY = "af_train.MORE"; private static final String _PREVIOUS_KEY = "af_train.PREVIOUS"; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(TrainRenderer.class); private static final String[] _EMPTY_STRING_ARRAY; private static final Map<String, String> _RESOURCE_KEY_MAP; static { _EMPTY_STRING_ARRAY = new String[0]; // Not adding the base link classes as before, those are a nuisance // while defining the skin since oyu cannot inhibit them as they're // on the same level as the train selectors. _RESOURCE_KEY_MAP = new TreeMap<String, String>(); _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_STYLE_CLASS, SkinSelectors.AF_TRAIN_LINK_STYLE_CLASS); _RESOURCE_KEY_MAP.put( SkinSelectors.LINK_DISABLED_STYLE_CLASS, SkinSelectors.AF_TRAIN_LINK_STYLE_CLASS); } }
/** User: Mahnaz Ebrahimi Date: Aug 30, 2008 */ public class JSFPagingTreeModel extends ChildPropertyTreeModel { private Object instance; private TreePagingModelFactory pagingModelFactory; private CoreTree tree; private CoreTreeTable treeTable; private int pageSize; private Object selectedObject; public JSFPagingTreeModel( Object instance, String childNameProperty, TreePagingModelFactory pagingModelFactory, CoreTree tree, int pageSize) { this.instance = instance; this.pagingModelFactory = pagingModelFactory; this.tree = tree; this.pageSize = pageSize; JSFPagedTableModel model = new JSFPagedTableModel(instance, pagingModelFactory, pageSize); JSFDefaultMutableTreeNode root = new JSFDefaultMutableTreeNode(instance); _path.add(root); root.childModel = model; super.setChildProperty(childNameProperty); } public JSFPagingTreeModel( Object instance, String childNameProperty, TreePagingModelFactory pagingModelFactory, CoreTreeTable treeTable, int pageSize) { this.instance = instance; this.pagingModelFactory = pagingModelFactory; this.treeTable = treeTable; this.pageSize = pageSize; JSFPagedTableModel model = new JSFPagedTableModel(instance, pagingModelFactory, pageSize); JSFDefaultMutableTreeNode root = new JSFDefaultMutableTreeNode(instance); _path.add(root); root.childModel = model; super.setChildProperty(childNameProperty); } public Object getRowKey() { final int sz = _path.size() - 1; Object lastRowkey = _getRowKey(); if ((sz == 0) && (lastRowkey == null)) return null; // root collection List<Object> path = new ArrayList<Object>(sz + 1); if (sz > 0) { for (int i = 0; i < sz; i++) { JSFDefaultMutableTreeNode node = _getNode(i); path.add(node.childModel.getRowKey()); } } path.add(lastRowkey); return path; } public void setRowKey(Object rowKey) { JSFDefaultMutableTreeNode root = _getNode(0); _path.clear(); _path.add(root); List<Object> path = (List<Object>) rowKey; if ((path == null) || (path.size() == 0)) { setRowIndex(-1); return; } int lastIndex = path.size() - 1; for (int i = 0; i < lastIndex; i++) { Object pathKey = path.get(i); _setRowKey(pathKey); enterContainer(); } _setRowKey(path.get(lastIndex)); } public int getRowCount() { return _getModel().getRowCount(); } public Object getRowData() { return _getModel().getRowData(); } public boolean isRowAvailable() { return _getModel().isRowAvailable(); } public boolean isContainer() { Object rowData = getRowData(); Object value = getChildData(rowData); if (value != null) { if (value instanceof Collection<?>) { return !((Collection<?>) value).isEmpty(); } else if (value.getClass().isArray()) { return Array.getLength(value) > 0; } else if (value instanceof DataModel) { return ((DataModel) value).getRowCount() > 0; } } return value != null; } public void enterContainer() { Object rowData = getRowData(); if (rowData == null) { throw new IllegalStateException(_LOG.getMessage("NULL_ROWDATA")); } JSFDefaultMutableTreeNode node = new JSFDefaultMutableTreeNode(rowData); _path.add(node); } public void exitContainer() { int sz = _path.size(); if (sz > 1) _path.remove(sz - 1); else throw new IllegalStateException(_LOG.getMessage("CANNOT_EXIT_ROOT_CONTAINER")); } public Object getContainerRowKey(Object childKey) { List<Object> path = (List<Object>) childKey; if ((path == null) || (path.size() <= 1)) return null; return new ArrayList<Object>(path.subList(0, path.size() - 1)); } public Object getWrappedData() { return _wrappedData; } public int getRowIndex() { return _getModel().getRowIndex(); } public void setRowIndex(int rowIndex) { _getModel().setRowIndex(rowIndex); } protected JSFPagedTableModel createChildModel(Object parent) { JSFPagedTableModel model = new JSFPagedTableModel(pagingModelFactory, parent); model.setRowIndex(-1); return model; } private Object _getRowKey() { return _getModel().getRowKey(); } private void _setRowKey(Object key) { _getModel().setRowKey(key); } private JSFDefaultMutableTreeNode _getCurrentNode() { return _getNode(_path.size() - 1); } private JSFDefaultMutableTreeNode _getNode(int index) { return _path.get(index); } private JSFPagedTableModel _getModel() { JSFDefaultMutableTreeNode node = _getCurrentNode(); JSFPagedTableModel model = node.getChildModel(); if (model == null) { model = createChildModel(node.getUserObject()); node.setChildModel(model); } return model; } public CoreTree getTree() { return tree; } public void setTree(CoreTree tree) { this.tree = tree; } public CoreTreeTable getTreeTable() { return treeTable; } public void setTreeTable(CoreTreeTable treeTable) { this.treeTable = treeTable; } public void selectionPerformed(SelectionEvent ev) { Object selected = getFirstRowKey(ev.getAddedSet()); if (selected == null) { Object unselected = getFirstRowKey(ev.getRemovedSet()); _getModel().setRowKey(unselected); // @todo if (isSelected(getRowData())) { setSelectedObject(null); } } else { _getModel().setRowKey(selected); // @todo setSelectedObject(getRowData()); } } private Object getFirstRowKey(RowKeySet set) { for (Object key : set) { return key; } return null; } public Object getSelectedObject() { return selectedObject; } public boolean isSelected(Object data) { return selectedObject != null && selectedObject.equals(data); } public void setSelectedObject(Object selectedObject) { this.selectedObject = selectedObject; } private final List<JSFDefaultMutableTreeNode> _path = new ArrayList<JSFDefaultMutableTreeNode>(5); private Object _wrappedData = null; private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ChildPropertyTreeModel.class); private class JSFDefaultMutableTreeNode extends DefaultMutableTreeNode { private JSFPagedTableModel childModel = null; private JSFDefaultMutableTreeNode() { this(null); } public JSFDefaultMutableTreeNode(Object userObject) { this(userObject, true, null); } public JSFDefaultMutableTreeNode( Object userObject, boolean allowsChildren, JSFPagedTableModel childModel) { super(userObject, allowsChildren); this.childModel = childModel; } public JSFPagedTableModel getChildModel() { return childModel; } public void setChildModel(JSFPagedTableModel childModel) { this.childModel = childModel; } } }
/** * Abstracts out the retrieval of ImageProviderResponses for dual ramp colorization. * * <p> * * @version $Name: $ ($Revision$) $Date$ * @deprecated This class comes from the old Java 1.2 UIX codebase and should not be used anymore. */ @Deprecated public abstract class AccentedLafIconProvider extends ColorizedLafIconProvider implements XhtmlLafConstants { /** Returns an icon, given its index. */ protected abstract Icon getIcon(IconKey iconKey); /** * Tests whether the the icon at the specified index is transparent. By default, all icons are * considered transparent. */ protected boolean isTransparent(IconKey iconKey) { return true; } protected abstract ImageProviderRequest createCoreIconRequest( ImageContext context, String source, Class<LookAndFeel> lookAndFeel, int direction, Color color, Color surroundingColor, NameResolver resolver); protected abstract ImageProviderRequest createAccentIconRequest( ImageContext context, String source, Class<LookAndFeel> lookAndFeel, int direction, Color color, Color surroundingColor, NameResolver resolver); /** Returns an image from the ImageProvider */ @Override public ImageProviderResponse getColorizedIcon(UIXRenderingContext context, IconKey iconKey) { ImageProvider provider = (ImageProvider) context.getProperty( ImageConstants.TECATE_NAMESPACE, ImageConstants.IMAGE_PROVIDER_PROPERTY); Icon icon = getIcon(iconKey); String iconName = null; if (icon != null) iconName = icon.getName(); if (provider == null) { if (_LOG.isWarning()) _LOG.warning("CANNOT_GET_IMAGE_PROVIDER_FOR_ICON", iconName); return null; } // Get the context and request objects ImageContext imageContext = context.getImageContext(); ImageProviderRequest request = _getIconRequest(context, iconKey); // Make the request ImageProviderResponse response = provider.getImage(imageContext, request); // Log any problems if (response == null) { if (_LOG.isWarning()) _LOG.warning("CANNOT_GET_COLORIZED_ICON", iconName); } return response; } // Returns the request object for the icon at the specified index private ImageProviderRequest _getIconRequest(UIXRenderingContext context, IconKey iconKey) { // We need three pieces of info for the icon request: Icon icon = getIcon(iconKey); // Get the index of the icon name in the _ICONS list String source = null; boolean isDirectionIndependent = false; boolean isCoreColor = false; Class<LookAndFeel> lookAndFeel = null; NameResolver resolver = null; if (icon != null) { source = icon.getName(); isDirectionIndependent = icon.isSymmetric(); isCoreColor = icon.isCoreColor(); lookAndFeel = icon.getLookAndFeel(); resolver = icon.getNameResolver(); } if (source == null) { _LOG.warning("CANNOT_FIND_ICON_WITH_GIVEN_KEY"); return null; } // Get the direction. If the source icon is symmetrical, we // always use the LTR version. int direction = -1; if (isDirectionIndependent) direction = LocaleUtils.DIRECTION_LEFTTORIGHT; else direction = LocaleUtils.getReadingDirection(context.getLocaleContext()); assert (direction != -1); // Get the color for this request. The color is either dark or // dark accent depending on whether the source icon uses core or // accent colors. Color color = null; ImageContext imageContext = context.getImageContext(); if (isCoreColor) color = _getCoreColor(context); else color = _getAccentColor(context); // Get the surrounding color for this icon. Color surroundingColor = _getSurroundingColor(context, iconKey); // =-=ags To avoid lots of object allocations, we might want // to keep a pool of IconRequest objects around or something. if (isCoreColor) { return createCoreIconRequest( imageContext, source, lookAndFeel, direction, color, surroundingColor, resolver); } return createAccentIconRequest( imageContext, source, lookAndFeel, direction, color, surroundingColor, resolver); } // Gets the Core color to use as the background color when // colorizing blue icons. private static Color _getCoreColor(UIXRenderingContext context) { return _getColor(context, BGCOLOR_DARK_STYLE_CLASS, _CORE_COLOR_KEY, _DEFAULT_CORE_COLOR); } // Gets the Accent color to use as the background color when // colorizing tan icons. private static Color _getAccentColor(UIXRenderingContext context) { return _getColor(context, BGACCENT_DARK_STYLE_CLASS, _ACCENT_COLOR_KEY, _DEFAULT_ACCENT_COLOR); } /** * Gets a Color stored as a property on the RenderingContext using the specified key. Or if not * found on, gets the color from the Ocelot StyleMap using the specified style class name. */ private static Color _getColor( UIXRenderingContext context, String styleClass, Object key, Color defaultColor) { // First check for the color on the RenderingContext Color color = (Color) context.getProperty(UIConstants.MARLIN_NAMESPACE, key); if (color != null) return color; // If the color hasn't been stored on the RenderingContext, get it // from the style map. StyleMap map = context.getStyleContext().getStyleMap(); if (map != null) { Style style = map.getStyleByClass(context.getStyleContext(), styleClass); if (style != null) { try { color = (Color) style.getParsedProperty(Style.BACKGROUND_KEY); } catch (PropertyParseException e) { // This should really be reported at parse time _LOG.info(e); } } } if (color == null) color = defaultColor; // Cache the color on the RenderingContext context.setProperty(UIConstants.MARLIN_NAMESPACE, key, color); return color; } // Return the surrounding color to use for the icon at // the specified index private Color _getSurroundingColor(UIXRenderingContext context, IconKey iconKey) { // If the image is transparent and the Agent does not support // transparent images, we grab the current background color off of // the style attrs stack if (isTransparent(iconKey) && !XhtmlLafUtils.supportsTransparentImages(context)) { return XhtmlLafUtils.getBackgroundColor(context); } return null; } // Keys for obtaining colorization colors from the RenderingContext private static final String _ACCENT_COLOR_KEY = "_accentColor"; private static final String _CORE_COLOR_KEY = "_coreColor"; // Default values for colorization colors private static final Color _DEFAULT_ACCENT_COLOR = new Color(204, 204, 153); private static final Color _DEFAULT_CORE_COLOR = new Color(51, 102, 153); private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(AccentedLafIconProvider.class); }