Remove legacy code following JSF 2.0 migration

- Remove JSF 1.2 components including ui package, faces-config.xml
  references and tld files
- Remove AjaxViewRoot class
- Polish JavaDocs

Issues: SWF-1536
This commit is contained in:
Phillip Webb
2012-06-27 13:58:43 -07:00
parent 73c34611a7
commit 2dea6c426a
52 changed files with 16 additions and 5637 deletions

View File

@@ -207,7 +207,6 @@ project('spring-faces') {
dependencies {
compile project(":spring-binding")
compile project(":spring-js")
compile project(":spring-webflow")
compile "commons-logging:commons-logging:1.1.1"

View File

@@ -25,8 +25,7 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* A concrete implementation of {@link AbstractAuthorizeTag} for use with standard Facelets rendering technology (JSF 2
* or higher).
* A concrete implementation of {@link AbstractAuthorizeTag} for use with standard Facelets rendering technology.
*
* @author Rossen Stoyanchev
* @since 2.2.0

View File

@@ -19,7 +19,7 @@ import java.io.IOException;
/**
* This class provides static methods that are registered as EL functions and available for use in Unified EL
* expressions in standard Facelets views (JSF 2 or higher).
* expressions in standard Facelets views.
*
* @author Rossen Stoyanchev
* @since 2.2.0

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2004-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.security;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
import javax.faces.view.facelets.TagHandler;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.TagAttribute;
/**
* A concrete implementation of {@link AbstractAuthorizeTag} for use with Facelets rendering technology in JSF 1.2
* environments.
*
* @author Rossen Stoyanchev
* @since 2.2.0
* @see FaceletsAuthorizeTag
*/
public class Jsf12FaceletsAuthorizeTag extends AbstractAuthorizeTag {
/**
* A class constructor for use in a {@link TagHandler}. Accepts all possible tag attributes as {@link TagAttribute}
* instances. The constructor extracts the attribute values by evaluating them as Unified EL expressions. This
* excludes the access attribute, which is expected to be a Spring EL expression.
*
* @param faceletContext the current FaceletContext
* @param access the access attribute or null
* @param url the url attribute or null
* @param method the method attribute or null
* @param ifAllGranted the ifAllGranted attribute or null
* @param ifAnyGranted the ifAnyGranted attribute or null
* @param ifNotGranted the ifNotGranted attribute or null
*/
public Jsf12FaceletsAuthorizeTag(FaceletContext faceletContext, TagAttribute access, TagAttribute url,
TagAttribute method, TagAttribute ifAllGranted, TagAttribute ifAnyGranted, TagAttribute ifNotGranted) {
setAccess(getAttributeValue(faceletContext, access, false));
setUrl(getAttributeValue(faceletContext, url, true));
setMethod(getAttributeValue(faceletContext, method, true));
setIfAllGranted(getAttributeValue(faceletContext, ifAllGranted, true));
setIfAnyGranted(getAttributeValue(faceletContext, ifAnyGranted, true));
setIfNotGranted(getAttributeValue(faceletContext, ifNotGranted, true));
}
/**
* A default constructor. Callers of this constructor are responsible for setting one or more of the tag attributes
* in {@link AbstractAuthorizeTag}.
*/
public Jsf12FaceletsAuthorizeTag() {
}
protected ServletRequest getRequest() {
return (ServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
}
protected ServletResponse getResponse() {
return (ServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
}
protected ServletContext getServletContext() {
return (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
}
/*---- Pirvate helper methods ----*/
private String getAttributeValue(FaceletContext faceletContext, TagAttribute tagAttribute, boolean evaluate) {
String value = null;
if (tagAttribute != null) {
if (evaluate) {
ValueExpression expression = tagAttribute.getValueExpression(faceletContext, String.class);
value = (String) expression.getValue(faceletContext.getFacesContext().getELContext());
} else {
value = tagAttribute.getValue();
}
}
return value;
}
}

View File

@@ -1,90 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.security;
import java.io.IOException;
import javax.faces.component.UIComponent;
import org.springframework.security.core.context.SecurityContextHolder;
import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagConfig;
import com.sun.facelets.tag.TagHandler;
/**
* A JSF 1.2 Facelets {@link TagHandler} for performing Spring Security authorization decisions. The tag supports the
* following combinations attributes for authorization:
* <ul>
* <li>access</li>
* <li>url, method</li>
* <li>ifAllGranted, ifAnyGranted, ifNotGranted</li>
* </ul>
* The var attribute can be used to store the result of the authorization decision for later use in the view.
*
* @author Rossen Stoyanchev
* @since 2.2.0
* @see Jsf12FaceletsAuthorizeTag
*/
public class Jsf12FaceletsAuthorizeTagHandler extends TagHandler {
private final TagAttribute access;
private final TagAttribute url;
private final TagAttribute method;
private final TagAttribute ifAllGranted;
private final TagAttribute ifAnyGranted;
private final TagAttribute ifNotGranted;
private final TagAttribute var;
/**
* @see TagHandler#TagHandler(TagConfig)
*/
public Jsf12FaceletsAuthorizeTagHandler(TagConfig config) {
super(config);
this.access = this.getAttribute("access");
this.url = this.getAttribute("url");
this.method = this.getAttribute("method");
this.ifAllGranted = this.getAttribute("ifAllGranted");
this.ifAnyGranted = this.getAttribute("ifAnyGranted");
this.ifNotGranted = this.getAttribute("ifNotGranted");
this.var = this.getAttribute("var");
}
/**
* @see TagHandler#apply(FaceletContext, UIComponent)
*/
public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
return;
}
Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag(faceletContext, this.access, this.url, this.method,
this.ifAllGranted, this.ifAnyGranted, this.ifNotGranted);
boolean isAuthorized = authorizeTag.authorize();
if (isAuthorized) {
this.nextHandler.apply(faceletContext, parent);
}
if (this.var != null) {
faceletContext.setAttribute(this.var.getValue(faceletContext), Boolean.valueOf(isAuthorized));
}
}
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2004-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.security;
import java.io.IOException;
/**
* This class provides static methods that are registered as EL functions and available for use in Unified EL
* expressions in JSF 1.2 Facelets views.
*
* @author Rossen Stoyanchev
* @since 2.2.0
*/
public abstract class Jsf12FaceletsAuthorizeTagUtils {
/**
* Returns true if the user has all of of the given authorities.
*
* @param authorities a comma-separated list of user authorities.
*/
public static boolean areAllGranted(String authorities) throws IOException {
Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
authorizeTag.setIfAllGranted(authorities);
return authorizeTag.authorizeUsingGrantedAuthorities();
}
/**
* Returns true if the user has any of the given authorities.
*
* @param authorities a comma-separated list of user authorities.
*/
public static boolean areAnyGranted(String authorities) throws IOException {
Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
authorizeTag.setIfAnyGranted(authorities);
return authorizeTag.authorizeUsingGrantedAuthorities();
}
/**
* Returns true if the user does not have any of the given authorities.
*
* @param authorities a comma-separated list of user authorities.
*/
public static boolean areNotGranted(String authorities) throws IOException {
Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
authorizeTag.setIfNotGranted(authorities);
return authorizeTag.authorizeUsingGrantedAuthorities();
}
/**
* Returns true if the user is allowed to access the given URL and HTTP method combination. The HTTP method is
* optional and case insensitive.
*/
public static boolean isAllowed(String url, String method) throws IOException {
Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag();
authorizeTag.setUrl(url);
authorizeTag.setMethod(method);
return authorizeTag.authorizeUsingUrlCheck();
}
}

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.ActionEvent;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Renderer for the {@code <sf:ajaxEvent>} tag.
*
* @author Jeremy Grelle
*
*/
public class AjaxEventInterceptorRenderer extends DojoElementDecorationRenderer {
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
String event = (String) component.getAttributes().get("event");
Assert.hasText(event, "The event attribute is required on " + component);
Assert.isTrue(component.getChildCount() == 1, "Exactly one child component is required for " + component);
ResourceHelper.beginScriptBlock(context);
ResponseWriter writer = context.getResponseWriter();
String processIds = (String) component.getAttributes().get("processIds");
if (StringUtils.hasText(processIds) && processIds.indexOf(component.getClientId(context)) == -1) {
processIds = component.getClientId(context) + ", " + processIds;
} else if (!StringUtils.hasText(processIds)) {
processIds = component.getClientId(context);
}
String childId = getElementId(context, component);
StringBuilder script = new StringBuilder();
script.append("dojo.addOnLoad(function(){");
script.append("Spring.addDecoration(new Spring.AjaxEventDecoration({");
script.append("event:'" + event + "'");
script.append(", elementId: '" + childId + "'");
script.append(", sourceId: '" + component.getClientId(context) + "'");
script.append(", formId : '" + RendererUtils.getFormId(context, component) + "'");
script.append(", params: {processIds : '" + processIds + "'");
script.append(", ajaxSource : '" + component.getClientId(context) + "'} }));});");
writer.writeText(script.toString(), null);
ResourceHelper.endScriptBlock(context);
}
private String getElementId(FacesContext context, UIComponent component) {
if (component.getChildCount() > 0) {
UIComponent child = component.getChildren().get(0);
if (!(child instanceof SpringJavascriptElementDecoration)) {
return child.getClientId(context);
} else {
return getElementId(context, child);
}
} else {
throw new FacesException("Could not locate a proper child element to trigger the ajax event.");
}
}
public void decode(FacesContext context, UIComponent component) {
if (context.getExternalContext().getRequestParameterMap().containsKey("ajaxSource")
&& context.getExternalContext().getRequestParameterMap().get("ajaxSource")
.equals(component.getClientId(context))) {
component.queueEvent(new ActionEvent(component));
}
}
}

View File

@@ -1,288 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import javax.faces.component.ContextCallback;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;
import javax.faces.lifecycle.Lifecycle;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.webflow.execution.View;
/**
* Customizes the behavior of an existing UIViewRoot with Ajax-aware processing.
*
* <p>
* This component is the key to rendering partial subtrees of the JSF component tree. It makes use of JSF 1.2's
* {@link UIComponent#invokeOnComponent(FacesContext, String, ContextCallback)} method to execute the various phases of
* the {@link Lifecycle} on each subtree.
* </p>
*
* @author Jeremy Grelle
* @author Nazaret Kazarian
*/
public class AjaxViewRoot extends DelegatingViewRoot {
public static final String AJAX_SOURCE_PARAM = "ajaxSource";
public static final String PROCESS_IDS_PARAM = "processIds";
protected static final String FORM_RENDERED = "formRendered";
protected static final String PROCESS_ALL = "*";
private final List<FacesEvent> events = new ArrayList<FacesEvent>();
private String[] processIds;
private String[] renderIds;
private static final String RENDER_IDS_EXPRESSION = "#{" + View.RENDER_FRAGMENTS_ATTRIBUTE + "}";
private final ValueBinding renderIdsExpr;
public AjaxViewRoot(UIViewRoot original) {
super(original);
this.renderIdsExpr = FacesContext.getCurrentInstance().getApplication().createValueBinding(RENDER_IDS_EXPRESSION);
if (!StringUtils.hasText(original.getId())) {
original.setId(createUniqueId());
}
swapChildren(original, this);
}
// implementing view root
public String getId() {
return getOriginalViewRoot().getId() + "_ajax";
}
public void queueEvent(FacesEvent event) {
Assert.notNull(event, "Cannot queue a null event.");
this.events.add(event);
}
public void encodeAll(FacesContext context) throws IOException {
for (int i = 0; i < getRenderIds().length; i++) {
String renderId = getRenderIds()[i];
ContextCallback callback = new ContextCallback() {
public void invokeContextCallback(FacesContext context, UIComponent target) {
try {
target.encodeAll(context);
if (target instanceof UIForm) {
context.getViewRoot().getAttributes().put(FORM_RENDERED, FORM_RENDERED);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
invokeOnComponent(context, renderId, callback);
}
swapChildren(this, getOriginalViewRoot());
context.setViewRoot(getOriginalViewRoot());
if (!getAttributes().containsKey(FORM_RENDERED)) {
context.getApplication().getViewHandler().writeState(context);
updateFormAction(context);
}
broadCastEvents(context, PhaseId.APPLY_REQUEST_VALUES);
}
public void processDecodes(FacesContext context) {
for (int i = 0; i < getProcessIds().length; i++) {
String processId = getProcessIds()[i];
ContextCallback callback = new ContextCallback() {
public void invokeContextCallback(FacesContext context, UIComponent target) {
target.processDecodes(context);
}
};
invokeOnComponent(context, processId, callback);
}
broadCastEvents(context, PhaseId.APPLY_REQUEST_VALUES);
}
public void processUpdates(FacesContext context) {
for (int i = 0; i < getProcessIds().length; i++) {
String processId = getProcessIds()[i];
ContextCallback callback = new ContextCallback() {
public void invokeContextCallback(FacesContext context, UIComponent target) {
target.processUpdates(context);
}
};
invokeOnComponent(context, processId, callback);
}
broadCastEvents(context, PhaseId.UPDATE_MODEL_VALUES);
}
public void processValidators(FacesContext context) {
for (int i = 0; i < getProcessIds().length; i++) {
String processId = getProcessIds()[i];
ContextCallback callback = new ContextCallback() {
public void invokeContextCallback(FacesContext context, UIComponent target) {
target.processValidators(context);
}
};
invokeOnComponent(context, processId, callback);
}
broadCastEvents(context, PhaseId.PROCESS_VALIDATIONS);
}
public void processApplication(FacesContext context) {
broadCastEvents(context, PhaseId.INVOKE_APPLICATION);
}
// subclassing hooks
protected String[] getProcessIds() {
if (this.processIds == null) {
FacesContext context = FacesContext.getCurrentInstance();
String processIdsParam = context.getExternalContext().getRequestParameterMap().get(PROCESS_IDS_PARAM);
if (StringUtils.hasText(processIdsParam) && processIdsParam.indexOf(PROCESS_ALL) != -1) {
this.processIds = new String[] { getOriginalViewRoot().getClientId(context) };
} else {
this.processIds = StringUtils.delimitedListToStringArray(processIdsParam, ",", " ");
this.processIds = removeNestedChildren(context, this.processIds);
}
}
return this.processIds;
}
protected String[] getRenderIds() {
if (this.renderIds == null) {
FacesContext context = FacesContext.getCurrentInstance();
this.renderIds = (String[]) this.renderIdsExpr.getValue(context);
if (this.renderIds == null || this.renderIds.length == 0) {
this.renderIds = getProcessIds();
} else {
this.renderIds = removeNestedChildren(context, this.renderIds);
}
}
return this.renderIds;
}
// internal helpers
private void swapChildren(UIViewRoot source, UIViewRoot target) {
target.getChildren().addAll(source.getChildren());
// Create a new list because the children of ViewRoot can change while we're iterating.
// For example:
// 1. child is an outputScript component with target="head"
// 2. child.setParent() fires PostAddToViewEvent
// 3. MyFaces HtmlScriptRenderer processes the event
// 3.1. creates javax.faces.Panel for "head"
// 3.2. adds outputScript to it
// 3.3. the parent of outputScript is changed from ViewRoot to "head" Panel component
// 4. outputScript is therefore no longer a child of ViewRoot
List<UIComponent> children = new ArrayList<UIComponent>(target.getChildren());
for (int i = 0; i < children.size(); i++) {
UIComponent child = children.get(i);
child.setParent(target);
}
}
private void updateFormAction(FacesContext context) {
ResponseWriter writer = context.getResponseWriter();
try {
String formId = findContainingFormId(context);
if (StringUtils.hasLength(formId)) {
String script = "dojo.byId('" + formId + "').action = '"
+ context.getApplication().getViewHandler().getActionURL(context, getViewId()) + "'";
ResourceHelper.beginScriptBlock(context);
writer.writeText(script, null);
ResourceHelper.endScriptBlock(context);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String findContainingFormId(FacesContext context) {
for (int i = 0; i < getRenderIds().length; i++) {
UIComponent component = context.getViewRoot().findComponent(getRenderIds()[i]);
Assert.notNull(component, "Component to be rendered with id '" + getRenderIds()[i]
+ "' could not be found.");
while (!(component instanceof UIViewRoot)) {
component = component.getParent();
if (component instanceof UIForm) {
return component.getClientId(context);
}
}
}
return null;
}
private String[] removeNestedChildren(FacesContext context, String[] ids) {
List<String> idList = Arrays.asList(ids);
final List<String> trimmedIds = new ArrayList<String>(idList);
for (final ListIterator<String> i = trimmedIds.listIterator(); i.hasNext();) {
String id = i.next();
invokeOnComponent(context, id, new ContextCallback() {
public void invokeContextCallback(FacesContext context, UIComponent component) {
while (!(component.getParent() instanceof UIViewRoot)) {
component = component.getParent();
if (trimmedIds.contains(component.getClientId(context))) {
i.remove();
}
}
}
});
}
return trimmedIds.toArray(new String[trimmedIds.size()]);
}
private void broadCastEvents(FacesContext context, PhaseId phaseId) {
List<FacesEvent> processedEvents = new ArrayList<FacesEvent>();
if (this.events.size() == 0) {
return;
}
boolean abort = false;
int phaseIdOrdinal = phaseId.getOrdinal();
for (FacesEvent event : this.events) {
int ordinal = event.getPhaseId().getOrdinal();
if (ordinal == PhaseId.ANY_PHASE.getOrdinal() || ordinal == phaseIdOrdinal) {
UIComponent source = event.getComponent();
try {
processedEvents.add(event);
source.broadcast(event);
} catch (AbortProcessingException e) {
abort = true;
break;
}
}
}
if (abort) {
this.events.clear();
} else {
this.events.removeAll(processedEvents);
}
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
/**
* Base {@link Renderer} for typical faces components, handling the rendering for common {@link UIComponent} attributes.
*
* @author Jeremy Grelle
*
*/
public abstract class BaseComponentRenderer extends BaseHtmlTagRenderer {
private Map<String, RenderAttributeCallback> attributeCallbacks;
private final RenderAttributeCallback idCallback = new RenderAttributeCallback() {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException {
writer.writeAttribute(attribute, component.getClientId(context), property);
}
};
private final RenderAttributeCallback disabledCallback = new RenderAttributeCallback() {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException {
if (Boolean.TRUE.equals(attributeValue)) {
writer.writeAttribute(attribute, "disabled", property);
}
}
};
protected Map<String, RenderAttributeCallback> getAttributeCallbacks(UIComponent component) {
if (this.attributeCallbacks == null) {
this.attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
this.attributeCallbacks.put("id", this.idCallback);
this.attributeCallbacks.put("name", this.idCallback);
this.attributeCallbacks.put("disabled", this.disabledCallback);
}
return this.attributeCallbacks;
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.faces.webflow.JsfUtils;
/**
* Base {@link Renderer} for components that require the Dojo implementation of Spring JavaScript to be available on the
* client.
*
* @author Jeremy Grelle
*
*/
public abstract class BaseDojoComponentRenderer extends BaseSpringJavascriptComponentRenderer {
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
super.encodeBegin(context, component);
if (!JsfUtils.isAsynchronousFlowRequest()) {
if (!context.getViewRoot().getAttributes().containsKey(DojoConstants.CUSTOM_THEME_PATH_SET)
&& !context.getViewRoot().getAttributes().containsKey(DojoConstants.CUSTOM_THEME_SET)) {
ResourceHelper.renderStyleLink(context, DojoConstants.DIJIT_THEME_PATH
+ DojoConstants.DEFAULT_DIJIT_THEME + "/" + DojoConstants.DEFAULT_DIJIT_THEME + ".css");
}
ResourceHelper.renderScriptLink(context, DojoConstants.DOJO_JS_RESOURCE_URI);
ResourceHelper.renderScriptLink(context, DojoConstants.SPRING_DOJO_JS_RESOURCE_URI);
}
}
}

View File

@@ -1,127 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Abstract base {@link Renderer} for a component that renders a standard HTML element.
*
* <p>
* Uses a callback mechanism for customizing the rendering of tag attributes when logic is required beyond a simple
* pass-through of the component attribute to the HTML attribute of the rendered element.
* </p>
*
* @author Jeremy Grelle
*/
abstract class BaseHtmlTagRenderer extends Renderer {
protected Log log = LogFactory.getLog(BaseHtmlTagRenderer.class);
/**
* Default {@link RenderAttributeCallback} that just renders the tag attribute as a pass-through value if the value
* is not null.
*/
private final RenderAttributeCallback defaultRenderAttributeCallback = new RenderAttributeCallback() {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException {
if (attributeValue != null) {
writer.writeAttribute(attribute, attributeValue, property);
}
}
};
/**
* Renders the opening portion of the tag, prior to any children.
*/
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement(getRenderedTagName(component), component);
writeAttributes(context, component);
}
/**
* Writes the attributes for this tag.
* @param context the current {@link FacesContext}
* @param component the {@link UIComponent} being rendered
* @throws IOException
*/
protected void writeAttributes(FacesContext context, UIComponent component) throws IOException {
for (int i = 0; i < getAttributesToRender(component).length; i++) {
try {
String attribute = getAttributesToRender(component)[i];
String property = attribute;
if (getAttributeAliases(component).containsKey(attribute)) {
property = getAttributeAliases(component).get(attribute);
}
Object attributeValue = component.getAttributes().get(property);
RenderAttributeCallback callback = this.defaultRenderAttributeCallback;
if (getAttributeCallbacks(null).containsKey(attribute)) {
callback = getAttributeCallbacks(component).get(attribute);
}
callback.doRender(context, context.getResponseWriter(), component, attribute, attributeValue, property);
} catch (IllegalArgumentException ex) {
// Attribute not found - Skip this attribute and continue
}
}
}
/**
* Closes the tag after children have been rendered.
*/
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.endElement(getRenderedTagName(component));
}
/**
* @param component TODO
* @return the name of the tag to be rendered.
*/
protected abstract String getRenderedTagName(UIComponent component);
/**
* @return an array of the tag attributes to be rendered
*/
protected abstract String[] getAttributesToRender(UIComponent component);
/**
* @return a map that returns the bean property name for any attribute that doesn't map directly (i.e., the 'class'
* attribute maps to the 'styleClass' bean property)
*/
protected Map<String, String> getAttributeAliases(UIComponent component) {
return HTML.STANDARD_ATTRIBUTE_ALIASES;
};
/**
* @return a map of registered RenderAttributeCallbacks for attributes that require special rendering logic
*/
protected Map<String, RenderAttributeCallback> getAttributeCallbacks(UIComponent component) {
return Collections.emptyMap();
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.faces.webflow.JsfUtils;
/**
* Base {@link Renderer} for components that require the Spring JavaScript library on the client.
*
* @author Jeremy Grelle
*
*/
public abstract class BaseSpringJavascriptComponentRenderer extends BaseComponentRenderer {
private final String springJsResourceUri = "/spring/Spring.js";
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
super.encodeBegin(context, component);
if (!JsfUtils.isAsynchronousFlowRequest()) {
ResourceHelper.renderScriptLink(context, this.springJsResourceUri);
}
}
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.faces.webflow.JsfUtils;
public abstract class BaseSpringJavascriptDecorationRenderer extends Renderer {
private final String springJsResourceUri = "/spring/Spring.js";
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
if (!JsfUtils.isAsynchronousFlowRequest()) {
ResourceHelper.renderScriptLink(context, this.springJsResourceUri);
}
}
}

View File

@@ -1,495 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.ContextCallback;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseListener;
/**
* Base class for wrapping an existing UIViewRoot to customize its behavior.
*
* @author Jeremy Grelle
*/
public abstract class DelegatingViewRoot extends UIViewRoot {
private final UIViewRoot original;
public DelegatingViewRoot(UIViewRoot original) {
this.original = original;
}
public UIViewRoot getOriginalViewRoot() {
return this.original;
}
/**
* @param phaseListener
* @see javax.faces.component.UIViewRoot#addPhaseListener(javax.faces.event.PhaseListener)
*/
public void addPhaseListener(PhaseListener phaseListener) {
this.original.addPhaseListener(phaseListener);
}
/**
* @param event
* @throws AbortProcessingException
* @see javax.faces.component.UIComponentBase#broadcast(javax.faces.event.FacesEvent)
*/
public void broadcast(FacesEvent event) throws AbortProcessingException {
this.original.broadcast(event);
}
/**
* @see javax.faces.component.UIViewRoot#createUniqueId()
*/
public String createUniqueId() {
return (this.original != null) ? this.original.createUniqueId() : null;
}
/**
* @param context
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context) {
this.original.decode(context);
}
/**
* @param context
* @throws IOException
* @see javax.faces.component.UIComponent#encodeAll(javax.faces.context.FacesContext)
*/
public void encodeAll(FacesContext context) throws IOException {
this.original.encodeAll(context);
}
/**
* @param context
* @throws IOException
* @see javax.faces.component.UIViewRoot#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException {
this.original.encodeBegin(context);
}
/**
* @param context
* @throws IOException
* @see javax.faces.component.UIComponentBase#encodeChildren(javax.faces.context.FacesContext)
*/
public void encodeChildren(FacesContext context) throws IOException {
this.original.encodeChildren(context);
}
/**
* @param context
* @throws IOException
* @see javax.faces.component.UIViewRoot#encodeEnd(javax.faces.context.FacesContext)
*/
public void encodeEnd(FacesContext context) throws IOException {
this.original.encodeEnd(context);
}
/**
* @param expr
* @see javax.faces.component.UIComponentBase#findComponent(java.lang.String)
*/
public UIComponent findComponent(String expr) {
return this.original.findComponent(expr);
}
/**
* @see javax.faces.component.UIViewRoot#getAfterPhaseListener()
*/
public MethodExpression getAfterPhaseListener() {
return this.original.getAfterPhaseListener();
}
/**
* @see javax.faces.component.UIComponentBase#getAttributes()
*/
public Map<String, Object> getAttributes() {
return this.original.getAttributes();
}
/**
* @see javax.faces.component.UIViewRoot#getBeforePhaseListener()
*/
public MethodExpression getBeforePhaseListener() {
return this.original.getBeforePhaseListener();
}
/**
* @see javax.faces.component.UIComponentBase#getChildCount()
*/
public int getChildCount() {
return this.original.getChildCount();
}
/**
* @see javax.faces.component.UIComponentBase#getChildren()
*/
public List<UIComponent> getChildren() {
return this.original.getChildren();
}
/**
* @param context
* @see javax.faces.component.UIComponentBase#getClientId(javax.faces.context.FacesContext)
*/
public String getClientId(FacesContext context) {
return this.original.getClientId(context);
}
/**
* @param ctx
* @see javax.faces.component.UIComponent#getContainerClientId(javax.faces.context.FacesContext)
*/
public String getContainerClientId(FacesContext ctx) {
return this.original.getContainerClientId(ctx);
}
/**
* @param name
* @see javax.faces.component.UIComponentBase#getFacet(java.lang.String)
*/
public UIComponent getFacet(String name) {
return this.original.getFacet(name);
}
/**
* @see javax.faces.component.UIComponentBase#getFacetCount()
*/
public int getFacetCount() {
return this.original.getFacetCount();
}
/**
* @see javax.faces.component.UIComponentBase#getFacets()
*/
public Map<String, UIComponent> getFacets() {
return this.original.getFacets();
}
/**
* @see javax.faces.component.UIComponentBase#getFacetsAndChildren()
*/
public Iterator<UIComponent> getFacetsAndChildren() {
return this.original.getFacetsAndChildren();
}
/**
* @see javax.faces.component.UIViewRoot#getFamily()
*/
public String getFamily() {
return this.original.getFamily();
}
/**
* @see javax.faces.component.UIComponentBase#getId()
*/
public String getId() {
return this.original.getId();
}
/**
* @see javax.faces.component.UIViewRoot#getLocale()
*/
public Locale getLocale() {
return this.original.getLocale();
}
/**
* @see javax.faces.component.UIComponentBase#getParent()
*/
public UIComponent getParent() {
return this.original.getParent();
}
/**
* @see javax.faces.component.UIComponentBase#getRendererType()
*/
public String getRendererType() {
return this.original.getRendererType();
}
/**
* @see javax.faces.component.UIViewRoot#getRenderKitId()
*/
public String getRenderKitId() {
return this.original.getRenderKitId();
}
/**
* @see javax.faces.component.UIComponentBase#getRendersChildren()
*/
public boolean getRendersChildren() {
return this.original.getRendersChildren();
}
/**
* @param name
* @deprecated
* @see javax.faces.component.UIComponentBase#getValueBinding(java.lang.String)
*/
public ValueBinding getValueBinding(String name) {
return this.original.getValueBinding(name);
}
/**
* @param name
* @see javax.faces.component.UIComponent#getValueExpression(java.lang.String)
*/
public ValueExpression getValueExpression(String name) {
return this.original.getValueExpression(name);
}
/**
* @see javax.faces.component.UIViewRoot#getViewId()
*/
public String getViewId() {
return this.original.getViewId();
}
/**
* @param context
* @param clientId
* @param callback
* @throws FacesException
* @see javax.faces.component.UIComponentBase#invokeOnComponent(javax.faces.context.FacesContext, java.lang.String,
* javax.faces.component.ContextCallback)
*/
public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
throws FacesException {
return this.original.invokeOnComponent(context, clientId, callback);
}
/**
* @see javax.faces.component.UIComponentBase#isRendered()
*/
public boolean isRendered() {
return this.original.isRendered();
}
/**
* @see javax.faces.component.UIComponentBase#isTransient()
*/
public boolean isTransient() {
return this.original.isTransient();
}
/**
* @see javax.faces.component.UIViewRoot#processApplication(javax.faces.context.FacesContext)
*/
public void processApplication(FacesContext context) {
this.original.processApplication(context);
}
/**
* @param context
* @see javax.faces.component.UIViewRoot#processDecodes(javax.faces.context.FacesContext)
*/
public void processDecodes(FacesContext context) {
this.original.processDecodes(context);
}
/**
* @param context
* @param state
* @see javax.faces.component.UIComponentBase#processRestoreState(javax.faces.context.FacesContext,
* java.lang.Object)
*/
public void processRestoreState(FacesContext context, Object state) {
this.original.processRestoreState(context, state);
}
/**
* @param context
* @see javax.faces.component.UIComponentBase#processSaveState(javax.faces.context.FacesContext)
*/
public Object processSaveState(FacesContext context) {
return this.original.processSaveState(context);
}
/**
* @param context
* @see javax.faces.component.UIViewRoot#processUpdates(javax.faces.context.FacesContext)
*/
public void processUpdates(FacesContext context) {
this.original.processUpdates(context);
}
/**
* @param context
* @see javax.faces.component.UIViewRoot#processValidators(javax.faces.context.FacesContext)
*/
public void processValidators(FacesContext context) {
this.original.processValidators(context);
}
/**
* @param event
* @see javax.faces.component.UIViewRoot#queueEvent(javax.faces.event.FacesEvent)
*/
public void queueEvent(FacesEvent event) {
this.original.queueEvent(event);
}
/**
* @param phaseListener
* @see javax.faces.component.UIViewRoot#removePhaseListener(javax.faces.event.PhaseListener)
*/
public void removePhaseListener(PhaseListener phaseListener) {
this.original.removePhaseListener(phaseListener);
}
/**
* @param facesContext
* @param state
* @see javax.faces.component.UIViewRoot#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
public void restoreState(FacesContext facesContext, Object state) {
this.original.restoreState(facesContext, state);
}
/**
* @param facesContext
* @see javax.faces.component.UIViewRoot#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext facesContext) {
return this.original.saveState(facesContext);
}
/**
* @param afterPhaseListener
* @see javax.faces.component.UIViewRoot#setAfterPhaseListener(javax.el.MethodExpression)
*/
public void setAfterPhaseListener(MethodExpression afterPhaseListener) {
this.original.setAfterPhaseListener(afterPhaseListener);
}
/**
* @param beforePhaseListener
* @see javax.faces.component.UIViewRoot#setBeforePhaseListener(javax.el.MethodExpression)
*/
public void setBeforePhaseListener(MethodExpression beforePhaseListener) {
this.original.setBeforePhaseListener(beforePhaseListener);
}
/**
* @param id
* @see javax.faces.component.UIComponentBase#setId(java.lang.String)
*/
public void setId(String id) {
// Test for null to deal with JSF setId on constructor
if (this.original != null) {
this.original.setId(id);
}
}
/**
* @param locale
* @see javax.faces.component.UIViewRoot#setLocale(java.util.Locale)
*/
public void setLocale(Locale locale) {
this.original.setLocale(locale);
}
/**
* @param parent
* @see javax.faces.component.UIComponentBase#setParent(javax.faces.component.UIComponent)
*/
public void setParent(UIComponent parent) {
this.original.setParent(parent);
}
/**
* @param rendered
* @see javax.faces.component.UIComponentBase#setRendered(boolean)
*/
public void setRendered(boolean rendered) {
this.original.setRendered(rendered);
}
/**
* @param rendererType
* @see javax.faces.component.UIComponentBase#setRendererType(java.lang.String)
*/
public void setRendererType(String rendererType) {
if (this.original != null) {
this.original.setRendererType(rendererType);
}
}
/**
* @param renderKitId
* @see javax.faces.component.UIViewRoot#setRenderKitId(java.lang.String)
*/
public void setRenderKitId(String renderKitId) {
this.original.setRenderKitId(renderKitId);
}
/**
* @param transientFlag
* @see javax.faces.component.UIComponentBase#setTransient(boolean)
*/
public void setTransient(boolean transientFlag) {
this.original.setTransient(transientFlag);
}
/**
* @param name
* @param binding
* @deprecated
* @see javax.faces.component.UIComponentBase#setValueBinding(java.lang.String, javax.faces.el.ValueBinding)
*/
public void setValueBinding(String name, ValueBinding binding) {
this.original.setValueBinding(name, binding);
}
/**
* @param name
* @param expression
* @see javax.faces.component.UIComponent#setValueExpression(java.lang.String, javax.el.ValueExpression)
*/
public void setValueExpression(String name, ValueExpression expression) {
this.original.setValueExpression(name, expression);
}
/**
* @param viewId
* @see javax.faces.component.UIViewRoot#setViewId(java.lang.String)
*/
public void setViewId(String viewId) {
this.original.setViewId(viewId);
}
}

View File

@@ -1,77 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
/**
* Component that uses the Dojo implementation of Spring JavaScript to decorate a child input component with client-side
* currency validation behavior.
*
* @author Jeremy Grelle
*
*/
public class DojoClientCurrencyValidator extends DojoWidget {
private static final String DOJO_COMPONENT_TYPE = "dijit.form.CurrencyTextBox";
private static final String[] DOJO_ATTRS_INTERNAL = new String[] { "currency" };
private static final String[] DOJO_ATTRS;
static {
DOJO_ATTRS = new String[DojoWidget.DOJO_ATTRS.length + DOJO_ATTRS_INTERNAL.length];
System.arraycopy(DojoWidget.DOJO_ATTRS, 0, DOJO_ATTRS, 0, DojoWidget.DOJO_ATTRS.length);
System.arraycopy(DOJO_ATTRS_INTERNAL, 0, DOJO_ATTRS, DojoWidget.DOJO_ATTRS.length, DOJO_ATTRS_INTERNAL.length);
}
private String currency;
public String getCurrency() {
if (this.currency != null) {
return this.currency;
}
ValueBinding exp = getValueBinding("currency");
return exp != null ? (String) exp.getValue(getFacesContext()) : null;
}
public void setCurrency(String currency) {
this.currency = currency;
}
protected String[] getDojoAttributes() {
return DOJO_ATTRS;
}
public String getWidgetType() {
return DOJO_COMPONENT_TYPE;
}
public Object saveState(FacesContext context) {
Object[] values = new Object[2];
values[0] = super.saveState(context);
values[1] = this.currency;
return values;
}
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
this.currency = (String) values[1];
}
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
import javax.faces.convert.DateTimeConverter;
import org.springframework.util.Assert;
/**
* Component that uses the Dojo implementation of Spring JavaScript to decorate a child input component with client-side
* date validation behavior.
*
* @author Jeremy Grelle
*
*/
public class DojoClientDateValidator extends DojoWidget {
private static final String DOJO_COMPONENT_TYPE = "dijit.form.DateTextBox";
private static final String[] DOJO_ATTRS_INTERNAL = new String[] { "datePattern" };
private static final String[] DOJO_ATTRS;
private String datePattern = null;
static {
DOJO_ATTRS = new String[DojoWidget.DOJO_ATTRS.length + DOJO_ATTRS_INTERNAL.length];
System.arraycopy(DojoWidget.DOJO_ATTRS, 0, DOJO_ATTRS, 0, DojoWidget.DOJO_ATTRS.length);
System.arraycopy(DOJO_ATTRS_INTERNAL, 0, DOJO_ATTRS, DojoWidget.DOJO_ATTRS.length, DOJO_ATTRS_INTERNAL.length);
}
public String getDatePattern() {
Assert.isTrue(getChildren().get(0) instanceof ValueHolder,
"Date validation can only be applied to an ValueHolder");
ValueHolder child = (ValueHolder) getChildren().get(0);
if (child.getConverter() instanceof DateTimeConverter) {
return ((DateTimeConverter) child.getConverter()).getPattern();
}
return this.datePattern;
}
public void setDatePattern(String datePattern) {
this.datePattern = datePattern;
}
protected String[] getDojoAttributes() {
return DOJO_ATTRS;
}
public String getWidgetType() {
return DOJO_COMPONENT_TYPE;
}
public Object saveState(FacesContext context) {
Object[] values = new Object[2];
values[0] = super.saveState(context);
values[1] = this.datePattern;
return values;
}
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
this.datePattern = (String) values[1];
}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
/**
* Component that uses the Dojo implementation of Spring JavaScript to decorate a child input component with client-side
* numeric validation behavior.
*
* @author Jeremy Grelle
*
*/
public class DojoClientNumberValidator extends DojoWidget {
private static final String DOJO_COMPONENT_TYPE = "dijit.form.NumberTextBox";
protected String[] getDojoAttributes() {
return DojoWidget.DOJO_ATTRS;
}
public String getWidgetType() {
return DOJO_COMPONENT_TYPE;
}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
/**
* Component that uses the Dojo implementation of Spring JavaScript to decorate a child input component with client-side
* text validation behavior.
*
* @author Jeremy Grelle
*
*/
public class DojoClientTextValidator extends DojoWidget {
private static final String DOJO_COMPONENT_TYPE = "dijit.form.ValidationTextBox";
protected String[] getDojoAttributes() {
return DojoWidget.DOJO_ATTRS;
}
public String getWidgetType() {
return DOJO_COMPONENT_TYPE;
}
}

View File

@@ -1,12 +0,0 @@
package org.springframework.faces.ui;
class DojoConstants {
static final String DIJIT_THEME_PATH = "/dijit/themes/";
static final String DEFAULT_DIJIT_THEME = "tundra";
static final String DOJO_JS_RESOURCE_URI = "/dojo/dojo.js";
static final String SPRING_DOJO_JS_RESOURCE_URI = "/spring/Spring-Dojo.js";
static final String CUSTOM_THEME_PATH_SET = "dojoCustomThemePathSet";
static final String CUSTOM_THEME_SET = "dojoCustomThemeSet";
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.faces.webflow.JsfUtils;
/**
* Generic renderer for components that use the Dojo implementation of Spring JavaScript to decorate a child component
* with enhanced client-side behavior.
*
* @author Jeremy Grelle
*
*/
public class DojoElementDecorationRenderer extends BaseSpringJavascriptDecorationRenderer {
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
super.encodeBegin(context, component);
if (!JsfUtils.isAsynchronousFlowRequest()) {
if (!context.getViewRoot().getAttributes().containsKey(DojoConstants.CUSTOM_THEME_PATH_SET)
&& !context.getViewRoot().getAttributes().containsKey(DojoConstants.CUSTOM_THEME_SET)) {
ResourceHelper.renderStyleLink(context, DojoConstants.DIJIT_THEME_PATH
+ DojoConstants.DEFAULT_DIJIT_THEME + "/" + DojoConstants.DEFAULT_DIJIT_THEME + ".css");
}
ResourceHelper.renderScriptLink(context, DojoConstants.DOJO_JS_RESOURCE_URI);
ResourceHelper.renderScriptLink(context, DojoConstants.SPRING_DOJO_JS_RESOURCE_URI);
}
}
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String selector;
if (component.getAttributes().containsKey("selector")) {
selector = "\"" + (String) component.getAttributes().get("selector") + "\"";
} else {
if (component.getChildCount() == 0) {
throw new FacesException(
"A Spring Faces elementDecoration expects either have a specified selector or at least one child component.");
}
selector = "dojo.byId('" + component.getChildren().get(0).getClientId(context) + "')";
}
ResourceHelper.beginScriptBlock(context);
StringBuilder script = new StringBuilder();
script.append(" dojo.addOnLoad(function(){dojo.query(" + selector + ").forEach(function(element){");
script.append(" Spring.addDecoration(new Spring.ElementDecoration({ ");
script.append(" elementId : element, ");
script.append(" widgetType : '" + component.getAttributes().get("widgetType") + "', ");
if (component.getAttributes().containsKey("widgetModule")) {
script.append(" widgetModule : '" + component.getAttributes().get("widgetModule") + "', ");
}
script.append(" widgetAttrs : { ");
String dojoAttrs = getDojoAttributesAsString(context, component);
script.append(dojoAttrs);
script.append(" }}));})});");
writer.writeText(script, null);
ResourceHelper.endScriptBlock(context);
}
protected String getDojoAttributesAsString(FacesContext context, UIComponent component) {
if (component.getAttributes().containsKey("widgetAttrs")) {
return (String) component.getAttributes().get("widgetAttrs");
} else {
return "";
}
}
}

View File

@@ -1,30 +0,0 @@
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
/**
* {@link Renderer} implementation that renders the JavaScript resources required by the Dojo versions of the Spring
* Faces components.
*
* @author Jeremy Grelle
*
*/
public class DojoScriptRenderer extends Renderer {
private static final String SPRING_JS_RESOURCE_URI = "/spring/Spring.js";
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
ResourceHelper.renderScriptLink(context, SPRING_JS_RESOURCE_URI);
ResourceHelper.renderScriptLink(context, DojoConstants.DOJO_JS_RESOURCE_URI);
ResourceHelper.renderScriptLink(context, DojoConstants.SPRING_DOJO_JS_RESOURCE_URI);
}
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
/**
* {@link Renderer} implementation that renders the CSS resources required by Dojo's widget system.
*
* @author Jeremy Grelle
*
*/
public class DojoStyleRenderer extends Renderer {
private static final String THEME_PATH_ATTR = "themePath";
private static final String THEME_ATTR = "theme";
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
String themePath = DojoConstants.DIJIT_THEME_PATH;
String theme = DojoConstants.DEFAULT_DIJIT_THEME;
if (component.getAttributes().containsKey(THEME_PATH_ATTR)) {
themePath = (String) component.getAttributes().get(THEME_PATH_ATTR);
context.getViewRoot().getAttributes().put(DojoConstants.CUSTOM_THEME_PATH_SET, true);
}
if (component.getAttributes().containsKey(THEME_ATTR)) {
theme = (String) component.getAttributes().get(THEME_ATTR);
context.getViewRoot().getAttributes().put(DojoConstants.CUSTOM_THEME_SET, true);
}
ResourceHelper.renderStyleLink(context, themePath + theme + "/" + theme + ".css");
}
}

View File

@@ -1,201 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
/**
* Base {@link UIComponent} for a component that uses the Dojo implementation of Spring JavaScript to decorate a child
* component with enhanced client-side behavior.
*
* @author Jeremy Grelle
*/
public abstract class DojoWidget extends SpringJavascriptElementDecoration {
protected static final String[] DOJO_ATTRS = new String[] { "disabled", "intermediateChanges", "tabIndex",
"required", "promptMessage", "invalidMessage", "constraints", "regExp", "regExpGen", "propercase",
"lowercase", "uppercase" };
private Boolean disabled;
private Boolean intermediateChanges;
private Integer tabIndex;
private Boolean required;
private String promptMessage;
private String invalidMessage;
private String constraints;
private String regExp;
private String regExpGen;
private Boolean lowercase;
private Boolean propercase;
private Boolean uppercase;
public Boolean getDisabled() {
if (this.disabled != null) {
return this.disabled;
}
ValueBinding exp = getValueBinding("disabled");
return exp != null ? (Boolean) exp.getValue(getFacesContext()) : null;
}
public void setDisabled(Boolean disabled) {
this.disabled = disabled;
}
public Boolean getIntermediateChanges() {
return this.intermediateChanges;
}
public void setIntermediateChanges(Boolean intermediateChanges) {
this.intermediateChanges = intermediateChanges;
}
public Integer getTabIndex() {
return this.tabIndex;
}
public void setTabIndex(Integer tabIndex) {
this.tabIndex = tabIndex;
}
public Boolean getRequired() {
return this.required;
}
public void setRequired(Boolean required) {
this.required = required;
}
public String getPromptMessage() {
if (this.promptMessage != null) {
return this.promptMessage;
}
ValueBinding exp = getValueBinding("promptMessage");
return exp != null ? (String) exp.getValue(getFacesContext()) : null;
}
public void setPromptMessage(String promptMessage) {
this.promptMessage = promptMessage;
}
public String getInvalidMessage() {
if (this.invalidMessage != null) {
return this.invalidMessage;
}
ValueBinding exp = getValueBinding("invalidMessage");
return exp != null ? (String) exp.getValue(getFacesContext()) : null;
}
public void setInvalidMessage(String invalidMessage) {
this.invalidMessage = invalidMessage;
}
public String getConstraints() {
return this.constraints;
}
public void setConstraints(String constraints) {
this.constraints = constraints;
}
public String getRegExp() {
return this.regExp;
}
public void setRegExp(String regExp) {
this.regExp = regExp;
}
public String getRegExpGen() {
return this.regExpGen;
}
public void setRegExpGen(String regExpGen) {
this.regExpGen = regExpGen;
}
public Boolean getLowercase() {
return this.lowercase;
}
public void setLowercase(Boolean lowercase) {
this.lowercase = lowercase;
}
public Boolean getUppercase() {
return this.uppercase;
}
public void setUppercase(Boolean uppercase) {
this.uppercase = uppercase;
}
public Boolean getPropercase() {
return this.propercase;
}
public void setPropercase(Boolean propercase) {
this.propercase = propercase;
}
protected abstract String[] getDojoAttributes();
public abstract String getWidgetType();
public Object saveState(FacesContext context) {
Object[] values = new Object[11];
values[0] = super.saveState(context);
values[1] = this.constraints;
values[2] = this.disabled;
values[3] = this.intermediateChanges;
values[4] = this.invalidMessage;
values[5] = this.promptMessage;
values[6] = this.regExp;
values[7] = this.regExpGen;
values[8] = this.required;
values[9] = this.tabIndex;
values[10] = this.propercase;
return values;
}
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
this.constraints = (String) values[1];
this.disabled = (Boolean) values[2];
this.intermediateChanges = (Boolean) values[3];
this.invalidMessage = (String) values[4];
this.promptMessage = (String) values[5];
this.regExp = (String) values[6];
this.regExpGen = (String) values[7];
this.required = (Boolean) values[8];
this.tabIndex = (Integer) values[9];
this.propercase = (Boolean) values[10];
}
}

View File

@@ -1,36 +0,0 @@
package org.springframework.faces.ui;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
public class DojoWidgetRenderer extends DojoElementDecorationRenderer {
protected String getDojoAttributesAsString(FacesContext context, UIComponent component) {
DojoWidget advisor = (DojoWidget) component;
StringBuilder attrs = new StringBuilder();
for (int i = 0; i < advisor.getDojoAttributes().length; i++) {
String key = advisor.getDojoAttributes()[i];
Object value = advisor.getAttributes().get(key);
if (value != null) {
if (attrs.length() > 0) {
attrs.append(", ");
}
attrs.append(key + " : ");
if (value instanceof String) {
attrs.append("'" + value + "'");
} else {
attrs.append(value.toString());
}
}
}
return attrs.toString();
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
/**
* A completely dynamic component that is used to back simple Facelets tags. Relies solely on the use of
* {@link UIComponent#getAttributes()} instead of JavaBean style getters and setters.
*
* @author Jeremy Grelle
*
*/
public class DynamicComponent extends UIComponentBase {
public String getFamily() {
return "spring.faces.DynamicComponent";
}
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.util.HashMap;
import java.util.Map;
/**
* Helper class that provides common attributes for standard HTML elements.
*
* @author Jeremy Grelle
*/
final class HTML {
/**
* Standard HTML attributes
*/
public static final String[] STANDARD_ATTRIBUTES = new String[] { "id", "class", "style", "title", "dir", "lang",
"accesskey", "tabindex" };
public static final Map<String, String> STANDARD_ATTRIBUTE_ALIASES = new HashMap<String, String>();
/**
* Standard window events - only valid in body and frameset elements
*/
public static final String[] WINDOW_EVENTS = new String[] { "onload", "onunload" };
/**
* Standard form events
*/
public static final String[] FORM_EVENTS = new String[] { "onsubmit", "onreset" };
/**
* Standard form element events
*/
public static final String[] COMMON_ELEMENT_EVENTS = new String[] { "onchange", "onselect", "onblur", "onfocus" };
/**
* Standard keyboard events
*/
public static final String[] KEYBOARD_EVENTS = new String[] { "onkeydown", "onkeypress", "onkeyup" };
/**
* Standard mouse events
*/
public static final String[] MOUSE_EVENTS = new String[] { "onclick", "ondblclick", "onmousedown", "onmousemove",
"onmouseout", "onmouseover", "onmouseup" };
/**
* Button attributes
*/
public static final String[] BUTTON_ATTRIBUTES = new String[] { "disabled", "name", "type", "value" };
/**
* Anchor attributes
*/
public static final String[] ANCHOR_ATTRIBUTES = new String[] { "charset", "coords", "href", "hreflang", "name",
"rel", "rev", "shape", "target", "type" };
static {
STANDARD_ATTRIBUTE_ALIASES.put("class", "styleClass");
}
}

View File

@@ -1,145 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.ActionEvent;
import javax.faces.render.Renderer;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* {@link Renderer} for the {@code <sf:commandButton>} tag.
*
* @author Jeremy Grelle
*/
public class ProgressiveCommandButtonRenderer extends BaseDojoComponentRenderer {
private static String[] ATTRIBUTES_TO_RENDER;
private static String INPUT_TAG_NAME = "input";
static {
List<String> attributes = new ArrayList<String>();
attributes.addAll(Arrays.asList(HTML.STANDARD_ATTRIBUTES));
attributes.addAll(Arrays.asList(HTML.BUTTON_ATTRIBUTES));
attributes.addAll(Arrays.asList(HTML.COMMON_ELEMENT_EVENTS));
attributes.addAll(Arrays.asList(HTML.KEYBOARD_EVENTS));
attributes.addAll(Arrays.asList(HTML.MOUSE_EVENTS));
ATTRIBUTES_TO_RENDER = attributes.toArray(new String[attributes.size()]);
}
private Map<String, RenderAttributeCallback> attributeCallbacks;
private final RenderAttributeCallback onclickCallback = new RenderAttributeCallback() {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException {
StringBuilder onclick = new StringBuilder();
if (attributeValue != null) {
String originalOnclick = attributeValue.toString().trim();
if (!originalOnclick.endsWith(";")) {
originalOnclick += ";";
}
onclick.append(originalOnclick);
}
Boolean ajaxEnabled = (Boolean) component.getAttributes().get("ajaxEnabled");
Boolean disabled = (Boolean) component.getAttributes().get("disabled");
String processIds = (String) component.getAttributes().get("processIds");
if (Boolean.TRUE.equals(ajaxEnabled) && Boolean.FALSE.equals(disabled)) {
if (StringUtils.hasText(processIds) && processIds.indexOf(component.getClientId(context)) == -1) {
processIds = component.getClientId(context) + ", " + processIds;
} else if (!StringUtils.hasText(processIds)) {
processIds = component.getClientId(context);
}
onclick.append("Spring.remoting.submitForm('" + component.getClientId(context) + "', ");
onclick.append("'" + RendererUtils.getFormId(context, component) + "', ");
onclick.append("{processIds: '" + processIds + "'" + encodeParamsAsObject(context, component)
+ "}); return false;");
} else {
onclick.append(getOnClickNoAjax(context, component));
}
if (onclick.length() > 0) {
writer.writeAttribute(attribute, onclick.toString(), property);
}
}
};
protected Map<String, RenderAttributeCallback> getAttributeCallbacks(UIComponent component) {
if (this.attributeCallbacks == null) {
this.attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
this.attributeCallbacks.putAll(super.getAttributeCallbacks(component));
this.attributeCallbacks.put("onclick", this.onclickCallback);
}
return this.attributeCallbacks;
}
/**
* This is a hook for subclasses to provide special onclick behavior in the non-ajax case
* @return the onclick value to use when Ajax is disabled.
*/
protected String getOnClickNoAjax(FacesContext context, UIComponent component) {
// No special behavior necessary for CommandButton
return "";
}
protected String[] getAttributesToRender(UIComponent component) {
return ATTRIBUTES_TO_RENDER;
}
protected String getRenderedTagName(UIComponent component) {
return INPUT_TAG_NAME;
}
public void decode(FacesContext context, UIComponent component) {
if (context.getExternalContext().getRequestParameterMap().containsKey(component.getClientId(context))) {
component.queueEvent(new ActionEvent(component));
}
}
public boolean getRendersChildren() {
return false;
}
protected String encodeParamsAsObject(FacesContext context, UIComponent component) {
StringBuilder paramObj = new StringBuilder();
for (int i = 0; i < component.getChildCount(); i++) {
if (component.getChildren().get(i) instanceof UIParameter) {
UIParameter param = (UIParameter) component.getChildren().get(i);
Assert.hasText(param.getName(),
"UIParameter requires a name when used as a child of a UICommand component");
paramObj.append(", " + param.getName() + " : '" + param.getValue() + "'");
}
}
return paramObj.toString();
}
}

View File

@@ -1,322 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
import org.springframework.beans.BeanUtils;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.faces.webflow.JsfUtils;
import org.springframework.util.Assert;
/**
* {@link Renderer} for the {@code <sf:commandLink>} tag.
*
* <p>
* This renderer is unique in that it first renders a button that will still work if JavaScript is disabled on the
* client, then progressively enhances the button and transforms it into a link if JavaScript is available.
* </p>
*
* @author Jeremy Grelle
*
*/
public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRenderer {
private static String[] ATTRIBUTES_TO_RENDER;
private static String[] ATTRIBUTES_TO_RENDER_WHEN_DISABLED;
private static String TAG_NAME = "a";
private static String TAG_NAME_WHEN_DISABLED = "span";
static {
List<String> attributes = new ArrayList<String>();
attributes.addAll(Arrays.asList(HTML.STANDARD_ATTRIBUTES));
attributes.addAll(Arrays.asList(HTML.COMMON_ELEMENT_EVENTS));
attributes.addAll(Arrays.asList(HTML.KEYBOARD_EVENTS));
attributes.addAll(Arrays.asList(HTML.MOUSE_EVENTS));
ATTRIBUTES_TO_RENDER_WHEN_DISABLED = attributes.toArray(new String[attributes.size()]);
attributes.addAll(Arrays.asList(HTML.ANCHOR_ATTRIBUTES));
ATTRIBUTES_TO_RENDER = attributes.toArray(new String[attributes.size()]);
}
private Map<String, RenderAttributeCallback> attributeCallbacks;
private final RenderAttributeCallback hrefCallback = new RenderAttributeCallback() {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException {
writer.writeAttribute(attribute, "#", property);
}
};
private final RenderAttributeCallback classCallback = new RenderAttributeCallback() {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException {
String classToAdd = "progressiveLink";
if (attributeValue != null) {
attributeValue = attributeValue.toString() + " " + classToAdd;
} else {
attributeValue = classToAdd;
}
writer.writeAttribute(attribute, attributeValue, property);
}
};
private final RenderAttributeCallback noOpCallback = new RenderAttributeCallback() {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException {
// No-op
}
};
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
if (isProgressiveCommandDisabled(component)) {
// Ideally this code should not be here. However, the base class inserts script links, which is even less
// than ideal when a link is disabled.
ResponseWriter writer = context.getResponseWriter();
writer.startElement(getRenderedTagName(component), component);
writeAttributes(context, component);
} else {
// No need to be progressive if this is an AJAX request since it can be assumed JavaScript is enabled
if (!JsfUtils.isAsynchronousFlowRequest()) {
// Render a plain submit button first if this is not an ajax request
ProgressiveUICommand button = new ProgressiveUICommand();
button.getAttributes().putAll(component.getAttributes());
BeanUtils.copyProperties(component, button);
button.setRendererType("spring.faces.ProgressiveCommandButtonRenderer");
button.setAjaxEnabled(false);
button.encodeBegin(context);
button.encodeChildren(context);
button.encodeEnd(context);
// Now render the link's HTML into a javascript variable
ResourceHelper.beginScriptBlock(context);
ResponseWriter writer = context.getResponseWriter();
String scriptVarStart = "var " + component.getClientId(context).replaceAll(":", "_") + "_link = \"";
writer.writeText(scriptVarStart, null);
writer = new DoubleQuoteEscapingWriter(writer);
context.setResponseWriter(writer);
}
super.encodeBegin(context, component);
}
}
public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
// If the link has no children, render out the "value" as text.
ResponseWriter writer = context.getResponseWriter();
String valueAttr = "value";
if (component.getAttributes().get(valueAttr) != null) {
writer.writeText(component.getAttributes().get(valueAttr), valueAttr);
}
super.encodeChildren(context, component);
}
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
if (isProgressiveCommandDisabled(component)) {
// Ideally this code should not be here. However, the base class inserts script links, which is even less
// than ideal when a link is disabled.
ResponseWriter writer = context.getResponseWriter();
writer.endElement(getRenderedTagName(component));
} else {
super.encodeEnd(context, component);
StringBuilder decorationParams = new StringBuilder();
decorationParams.append("{");
decorationParams.append("elementId : '" + component.getClientId(context) + "'");
ResponseWriter writer = context.getResponseWriter();
// Close the script variable started in encodeBegin if this is not an AJAX request
if (!JsfUtils.isAsynchronousFlowRequest()) {
DoubleQuoteEscapingWriter tempWriter = (DoubleQuoteEscapingWriter) writer;
String scriptVarValue = tempWriter.escapeResult();
context.setResponseWriter(tempWriter.original);
writer = tempWriter.original;
writer.writeText(scriptVarValue, null);
String scriptVarEnd = "\";\n";
writer.writeText(scriptVarEnd, null);
decorationParams
.append(", linkHtml : " + component.getClientId(context).replaceAll(":", "_") + "_link");
ResourceHelper.endScriptBlock(context);
}
decorationParams.append("}");
StringBuilder advisorScript = new StringBuilder();
advisorScript.append("Spring.addDecoration(new Spring.CommandLinkDecoration(" + decorationParams.toString()
+ "));");
ResourceHelper.beginScriptBlock(context);
writer.writeText(advisorScript, null);
ResourceHelper.endScriptBlock(context);
}
}
public boolean getRendersChildren() {
return true;
}
protected String[] getAttributesToRender(UIComponent component) {
return isProgressiveCommandDisabled(component) ? ATTRIBUTES_TO_RENDER_WHEN_DISABLED : ATTRIBUTES_TO_RENDER;
}
protected String getRenderedTagName(UIComponent component) {
return isProgressiveCommandDisabled(component) ? TAG_NAME_WHEN_DISABLED : TAG_NAME;
}
protected Map<String, RenderAttributeCallback> getAttributeCallbacks(UIComponent component) {
if (this.attributeCallbacks == null) {
this.attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
this.attributeCallbacks.putAll(super.getAttributeCallbacks(component));
this.attributeCallbacks.put("href", this.hrefCallback);
this.attributeCallbacks.put("class", this.classCallback);
this.attributeCallbacks.put("type", this.noOpCallback);
}
return this.attributeCallbacks;
}
protected String getOnClickNoAjax(FacesContext context, UIComponent component) {
if (isProgressiveCommandDisabled(component)) {
return "";
} else {
String params = encodeParamsAsArray(context, component);
StringBuilder onclick = new StringBuilder();
onclick.append("this.submitFormFromLink('" + RendererUtils.getFormId(context, component) + "','"
+ component.getClientId(context) + "', " + params + "); return false;");
return onclick.toString();
}
}
protected String encodeParamsAsArray(FacesContext context, UIComponent component) {
StringBuilder paramArray = new StringBuilder();
paramArray.append("[");
for (int i = 0; i < component.getChildCount(); i++) {
if (component.getChildren().get(i) instanceof UIParameter) {
UIParameter param = (UIParameter) component.getChildren().get(i);
Assert.hasText(param.getName(),
"UIParameter requires a name when used as a child of a UICommand component");
if (paramArray.length() > 1) {
paramArray.append(", ");
}
paramArray.append("{name : '" + param.getName() + "'");
paramArray.append(", value : '" + param.getValue() + "'}");
}
}
paramArray.append("]");
return paramArray.toString();
}
private Boolean isProgressiveCommandDisabled(UIComponent component) {
return ((ProgressiveUICommand) component).getDisabled();
}
private class DoubleQuoteEscapingWriter extends ResponseWriter {
private final ResponseWriter original;
private final ResponseWriter clonedWriter;
private final StringWriter buffer = new StringWriter();
public DoubleQuoteEscapingWriter(ResponseWriter original) {
this.original = original;
this.clonedWriter = original.cloneWithWriter(this.buffer);
}
public String escapeResult() {
String result = this.buffer.toString();
result = result.replaceAll("\\\"", "\\\\\"");
return result;
}
public ResponseWriter cloneWithWriter(Writer arg0) {
return this.clonedWriter.cloneWithWriter(arg0);
}
public void endDocument() throws IOException {
this.clonedWriter.endDocument();
}
public void endElement(String arg0) throws IOException {
this.clonedWriter.endElement(arg0);
}
public void flush() throws IOException {
this.clonedWriter.flush();
}
public String getCharacterEncoding() {
return this.clonedWriter.getCharacterEncoding();
}
public String getContentType() {
return this.clonedWriter.getContentType();
}
public void startDocument() throws IOException {
this.clonedWriter.startDocument();
}
public void startElement(String arg0, UIComponent arg1) throws IOException {
this.clonedWriter.startElement(arg0, arg1);
}
public void writeAttribute(String arg0, Object arg1, String arg2) throws IOException {
this.clonedWriter.writeAttribute(arg0, arg1, arg2);
}
public void writeComment(Object arg0) throws IOException {
this.clonedWriter.writeComment(arg0);
}
public void writeText(char[] arg0, int arg1, int arg2) throws IOException {
this.clonedWriter.writeText(arg0, arg1, arg2);
}
public void writeText(Object arg0, String arg1) throws IOException {
this.clonedWriter.writeText(arg0, arg1);
}
public void writeURIAttribute(String arg0, Object arg1, String arg2) throws IOException {
this.clonedWriter.writeURIAttribute(arg0, arg1, arg2);
}
public void close() throws IOException {
this.clonedWriter.close();
}
public void write(char[] cbuf, int off, int len) throws IOException {
this.clonedWriter.write(cbuf, off, len);
}
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import org.springframework.webflow.definition.TransitionDefinition;
import org.springframework.webflow.engine.TransitionableState;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.RequestContextHolder;
/**
* {@link UIComponent} implementation that backs the {@code <sf:commandButton>} tag. Relies mainly on the use of
* {@link UIComponent#getAttributes()} as opposed to JavaBean getters and setters, except for attribute that require
* type conversion.
*
* @author Jeremy Grelle
*/
public class ProgressiveUICommand extends UICommand {
private String type = "submit";
private Boolean disabled;
private Boolean ajaxEnabled = true;
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public Boolean getDisabled() {
if (this.disabled != null) {
return this.disabled;
}
ValueBinding vb = getValueBinding("disabled");
return vb != null ? (Boolean) vb.getValue(getFacesContext()) : false;
}
public void setDisabled(Boolean disabled) {
this.disabled = disabled;
}
public Boolean getAjaxEnabled() {
return this.ajaxEnabled;
}
public void setAjaxEnabled(Boolean ajaxEnabled) {
this.ajaxEnabled = ajaxEnabled;
}
public boolean isImmediate() {
RequestContext context = RequestContextHolder.getRequestContext();
if (context != null && getActionExpression().isLiteralText()
&& context.getCurrentState() instanceof TransitionableState) {
TransitionDefinition transition = context
.getMatchingTransition(getActionExpression().getExpressionString());
if (transition != null && transition.getAttributes().contains("bind")) {
return Boolean.FALSE.equals(transition.getAttributes().getBoolean("bind"));
}
}
return super.isImmediate();
}
public Object saveState(FacesContext context) {
Object[] values = new Object[4];
values[0] = super.saveState(context);
values[1] = this.type;
values[2] = this.disabled;
values[3] = this.ajaxEnabled;
return values;
}
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
this.type = (String) values[1];
this.disabled = (Boolean) values[2];
this.ajaxEnabled = (Boolean) values[3];
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
/**
* Callback interface used to provide custom behavior for the rendering of a particular component attribute.
*
* @author Jeremy Grelle
*
*/
interface RenderAttributeCallback {
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
Object attributeValue, String property) throws IOException;
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
/**
* Helper class for common renderer functionality.
*
* @author Jeremy Grelle
*
*/
class RendererUtils {
public static String getFormId(FacesContext context, UIComponent component) {
if (component.getParent() instanceof UIForm) {
return component.getParent().getClientId(context);
} else if (component.getParent() instanceof UIViewRoot) {
throw new FacesException("Could not render " + component.getClass().getName() + " component with id "
+ component.getId() + " - no enclosing UIForm was found.");
} else {
return getFormId(context, component.getParent());
}
}
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
/**
* {@link Renderer} for the {@code <sf:resourceGroup>} tag.
*
* <p>
* This render outputs a specially formatted Javascript or CSS include that requests multiple resources with one HTTP
* request.
* </p>
*
* @author Jeremy Grelle
*
* TODO - Make this work with Javacript resources
*/
public class ResourceGroupRenderer extends Renderer {
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
if (component.getChildCount() > 0) {
ResourceHelper.beginCombineStyles(context);
}
}
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
if (component.getChildCount() > 0) {
ResourceHelper.endCombineStyles(context);
}
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
import org.springframework.js.resource.ResourceServlet;
import org.springframework.util.Assert;
/**
* {@link Renderer} for the {@code <sf:resource>} tag.
*
* <p>
* Renders a Javascript or CSS include with a URL properly formatted to map to the {@link ResourceServlet}.
* </p>
*
* @author Jeremy Grelle
*/
public class ResourceRenderer extends Renderer {
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
String resourcePath = (String) component.getAttributes().get("path");
Assert.hasText(resourcePath, "Resource component " + component.getClientId(context) + " is missing a path.");
if (!resourcePath.startsWith("/")) {
resourcePath = "/" + resourcePath;
component.getAttributes().put("path", resourcePath);
}
ResourceHelper.renderResource(context, resourcePath);
}
}

View File

@@ -1,12 +0,0 @@
package org.springframework.faces.ui;
import javax.faces.component.UIComponentBase;
public class SpringJavascriptElementDecoration extends UIComponentBase {
public String getFamily() {
return "spring.faces.Decoration";
}
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui;
import java.io.IOException;
import javax.faces.FacesException;
import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
import org.springframework.faces.ui.resource.ResourceHelper;
/**
* {@link Renderer} for the {@code <sf:validateAllOnClick>} tag.
*
* @author Jeremy Grelle
*
*/
public class ValidateAllRenderer extends BaseSpringJavascriptDecorationRenderer {
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
if (component.getChildCount() == 0) {
throw new FacesException("A Spring Faces advisor expects to have at least one child component.");
}
if (!(component.getChildren().get(0) instanceof UICommand)) {
throw new FacesException("ValidateAll expects to have a child of type UICommand.");
}
UIComponent advisedChild = component.getChildren().get(0);
ResourceHelper.beginScriptBlock(context);
StringBuilder script = new StringBuilder();
script.append("Spring.addDecoration(new Spring.ValidateAllDecoration({" + "event : 'onclick', "
+ "elementId : '" + advisedChild.getClientId(context) + "'}));");
writer.writeText(script, null);
ResourceHelper.endScriptBlock(context);
}
}

View File

@@ -1,5 +0,0 @@
<html>
<body>
<p>Spring Faces component library.</p>
</body>
</html>

View File

@@ -1,212 +0,0 @@
/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.faces.ui.resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.springframework.js.resource.ResourceServlet;
/**
* Helper used by Spring Faces component renderers to add links to javascript and css resources. The resource links will
* be rendered in the correct format for the requests to be handled by the Spring JavaScript {@link ResourceServlet}.
* The resource paths are cached so that a particular resource link is only rendered once per request.
*
* @author Jeremy Grelle
*
*/
public class ResourceHelper {
private static final String RENDERED_RESOURCES_KEY = "org.springframework.faces.RenderedResources";
private static final String COMBINED_RESOURCES_KEY = "org.springframework.faces.CombinedResources";
private static final String SCRIPT_BLOCK_ESCAPE_BEGIN = "<!--//--><![CDATA[//><!--\n";
private static final String SCRIPT_BLOCK_ESCAPE_END = "\n//--><!]]>";
private static final String SCRIPT_ELEMENT = "script";
private ResourceHelper() {
}
/**
* Renders either a script or style resource depending on the resourcePath
* @param facesContext
* @param resourcePath
* @throws IOException
*/
public static void renderResource(FacesContext facesContext, String resourcePath) throws IOException {
if (resourcePath.endsWith(".js")) {
renderScriptLink(facesContext, resourcePath);
} else if (resourcePath.endsWith(".css")) {
renderStyleLink(facesContext, resourcePath);
}
}
/**
* Render a <code><script/></code> tag for a given script resource.
* @param facesContext
* @param scriptPath
* @throws IOException
*/
public static void renderScriptLink(FacesContext facesContext, String scriptPath) throws IOException {
renderScriptLink(facesContext, scriptPath, Collections.<String, Object> emptyMap());
}
/**
* Render a <code><script/></code> tag for a given script resource.
* @param facesContext
* @param scriptPath
* @param attributes - a map of additional attributes to render on the script tag
* @throws IOException
*/
public static void renderScriptLink(FacesContext facesContext, String scriptPath, Map<String, Object> attributes)
throws IOException {
if (alreadyRendered(facesContext, scriptPath)) {
return;
}
ResponseWriter writer = facesContext.getResponseWriter();
writer.startElement(SCRIPT_ELEMENT, null);
writer.writeAttribute("type", "text/javascript", null);
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
writer.writeAttribute(entry.getKey(), entry.getValue(), null);
}
String src = facesContext.getExternalContext().getRequestContextPath() + "/resources" + scriptPath;
writer.writeAttribute("src", src, null);
writer.endElement(SCRIPT_ELEMENT);
markRendered(facesContext, scriptPath);
}
/**
* Render a <code><link/></code> tag for a given stylesheet resource.
* @param facesContext
* @param cssPath
* @throws IOException
*/
public static void renderStyleLink(FacesContext facesContext, String cssPath) throws IOException {
if (alreadyRendered(facesContext, cssPath)) {
return;
} else if (isCombineStyles(facesContext)) {
addStyle(facesContext, cssPath);
return;
}
ResponseWriter writer = facesContext.getResponseWriter();
writer.startElement("link", null);
writer.writeAttribute("type", "text/css", null);
writer.writeAttribute("rel", "stylesheet", null);
String src = facesContext.getExternalContext().getRequestContextPath() + "/resources" + cssPath;
writer.writeAttribute("href", src, null);
writer.endElement("link");
markRendered(facesContext, cssPath);
}
/**
* Render a <code><script/></code> tag for a given dojo include.
* @param facesContext
* @param module
* @throws IOException
*/
public static void renderDojoInclude(FacesContext facesContext, String module) throws IOException {
if (alreadyRendered(facesContext, module)) {
return;
}
ResponseWriter writer = facesContext.getResponseWriter();
writer.startElement(SCRIPT_ELEMENT, null);
writer.writeAttribute("type", "text/javascript", null);
writer.writeText("dojo.require('" + module + "');", null);
writer.endElement(SCRIPT_ELEMENT);
markRendered(facesContext, module);
}
public static void beginCombineStyles(FacesContext facesContext) {
List<String> combinedResources = new ArrayList<String>();
facesContext.getExternalContext().getRequestMap().put(COMBINED_RESOURCES_KEY, combinedResources);
}
private static boolean isCombineStyles(FacesContext facesContext) {
return facesContext.getExternalContext().getRequestMap().containsKey(COMBINED_RESOURCES_KEY);
}
private static void addStyle(FacesContext facesContext, String stylePath) {
List<String> combinedResources = getCombinedResources(facesContext);
combinedResources.add(stylePath);
}
public static void endCombineStyles(FacesContext facesContext) throws IOException {
List<String> combinedResources = getCombinedResources(facesContext);
StringBuilder combinedPath = new StringBuilder();
for (int i = 0; i < combinedResources.size(); i++) {
String resourcePath = combinedResources.get(i);
if (i == 1) {
combinedPath.append("?appended=");
}
if (i > 1) {
combinedPath.append(",");
}
combinedPath.append(resourcePath);
}
renderStyleLink(facesContext, combinedPath.toString());
}
public static void beginScriptBlock(FacesContext facesContext) throws IOException {
ResponseWriter writer = facesContext.getResponseWriter();
writer.startElement(SCRIPT_ELEMENT, null);
writer.writeAttribute("type", "text/javascript", null);
writer.writeText(SCRIPT_BLOCK_ESCAPE_BEGIN, null);
}
public static void endScriptBlock(FacesContext facesContext) throws IOException {
ResponseWriter writer = facesContext.getResponseWriter();
writer.writeText(SCRIPT_BLOCK_ESCAPE_END, null);
writer.endElement(SCRIPT_ELEMENT);
}
private static void markRendered(FacesContext facesContext, String scriptPath) {
Set<String> renderedResources = getRenderedResources(facesContext);
if (renderedResources == null) {
renderedResources = new HashSet<String>();
facesContext.getExternalContext().getRequestMap().put(RENDERED_RESOURCES_KEY, renderedResources);
}
renderedResources.add(scriptPath);
}
private static boolean alreadyRendered(FacesContext facesContext, String scriptPath) {
Set<String> renderedResources = getRenderedResources(facesContext);
return renderedResources != null && renderedResources.contains(scriptPath);
}
@SuppressWarnings("unchecked")
private static List<String> getCombinedResources(FacesContext facesContext) {
return (List<String>) facesContext.getExternalContext().getRequestMap().get(COMBINED_RESOURCES_KEY);
}
@SuppressWarnings("unchecked")
private static Set<String> getRenderedResources(FacesContext facesContext) {
return (Set<String>) facesContext.getExternalContext().getRequestMap().get(RENDERED_RESOURCES_KEY);
}
}

View File

@@ -1,5 +0,0 @@
<html>
<body>
<p>Support for providing JavaScript, CSS, and image resources needed by Spring Faces components.</p>
</body>
</html>

View File

@@ -30,7 +30,6 @@ import javax.faces.render.RenderKitWrapper;
import javax.faces.render.ResponseStateManager;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.util.ClassUtils;
public class FlowRenderKit extends RenderKitWrapper {

View File

@@ -31,10 +31,20 @@ import org.springframework.webflow.execution.RequestContext;
*/
public class JsfRuntimeInformation {
/** JSF Version 1.1 */
/**
* JSF Version 1.1
*
* @deprecated As of Web Flow 2.4.0 JSF 2.0 is a minimum requirement
*/
@Deprecated
public static final int JSF_11 = 0;
/** JSF Version 1.2 */
/**
* JSF Version 1.2
*
* @deprecated As of Web Flow 2.4.0 JSF 2.0 is a minimum requirement
*/
@Deprecated
public static final int JSF_12 = 1;
/** JSF Version 2.0 */

View File

@@ -24,7 +24,6 @@ import javax.faces.lifecycle.Lifecycle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.faces.ui.AjaxViewRoot;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.View;
@@ -120,11 +119,7 @@ public class JsfView implements View {
*/
public void saveState() {
FacesContext facesContext = FlowFacesContext.getCurrentInstance();
if (this.viewRoot instanceof AjaxViewRoot) {
facesContext.setViewRoot(((AjaxViewRoot) this.viewRoot).getOriginalViewRoot());
} else {
facesContext.setViewRoot(this.viewRoot);
}
facesContext.setViewRoot(this.viewRoot);
facesContext.getApplication().getStateManager().saveView(facesContext);
}

View File

@@ -31,17 +31,11 @@ import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import javax.faces.event.PhaseId;
import javax.faces.lifecycle.Lifecycle;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.binding.expression.Expression;
import org.springframework.faces.ui.AjaxViewRoot;
import org.springframework.js.ajax.SpringJavascriptAjaxHandler;
import org.springframework.util.Assert;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.View;
import org.springframework.webflow.execution.ViewFactory;
@@ -58,8 +52,6 @@ public class JsfViewFactory implements ViewFactory {
private static final Log logger = LogFactory.getLog(JsfViewFactory.class);
private static SpringJavascriptAjaxHandler springJsAjaxHandler = new SpringJavascriptAjaxHandler();
private final Expression viewIdExpression;
private final Lifecycle lifecycle;
@@ -96,7 +88,7 @@ public class JsfViewFactory implements ViewFactory {
if (notifyPhaseListeners) {
JsfUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, this.lifecycle, facesContext);
}
return createJsfView(viewRoot, this.lifecycle, context);
return new JsfView(viewRoot, this.lifecycle, context);
}
private UIViewRoot getViewRoot(RequestContext context, FacesContext facesContext) {
@@ -161,23 +153,6 @@ public class JsfViewFactory implements ViewFactory {
return viewRoot;
}
private JsfView createJsfView(UIViewRoot root, Lifecycle lifecycle, RequestContext context) {
if (isSpringJavascriptAjaxRequest(context.getExternalContext())) {
root = new AjaxViewRoot(root);
}
return new JsfView(root, lifecycle, context);
}
private boolean isSpringJavascriptAjaxRequest(ExternalContext context) {
// consider factoring out into external context
if (context.getNativeContext() instanceof ServletContext) {
return springJsAjaxHandler.isAjaxRequest((HttpServletRequest) context.getNativeRequest(),
(HttpServletResponse) context.getNativeResponse());
} else {
return false;
}
}
/**
* Walk the component tree to perform any required per-component operations.
*

View File

@@ -18,129 +18,10 @@
<lifecycle>
<phase-listener>org.springframework.faces.support.RequestLoggingPhaseListener</phase-listener>
</lifecycle>
<component>
<component-type>spring.faces.ProgressiveCommandButton</component-type>
<component-class>org.springframework.faces.ui.ProgressiveUICommand</component-class>
</component>
<component>
<component-type>spring.faces.ProgressiveCommandLink</component-type>
<component-class>org.springframework.faces.ui.ProgressiveUICommand</component-class>
</component>
<component>
<component-type>spring.faces.AjaxEventInterceptor</component-type>
<component-class>javax.faces.component.UICommand</component-class>
</component>
<component>
<component-type>spring.faces.DojoIncludeStyles</component-type>
<component-class>org.springframework.faces.ui.DynamicComponent</component-class>
</component>
<component>
<component-type>spring.faces.DojoIncludeScripts</component-type>
<component-class>org.springframework.faces.ui.DynamicComponent</component-class>
</component>
<component>
<component-type>spring.faces.ResourceGroup</component-type>
<component-class>org.springframework.faces.ui.DynamicComponent</component-class>
</component>
<component>
<component-type>spring.faces.Resource</component-type>
<component-class>org.springframework.faces.ui.DynamicComponent</component-class>
</component>
<component>
<component-type>spring.faces.DojoClientTextValidator</component-type>
<component-class>org.springframework.faces.ui.DojoClientTextValidator</component-class>
</component>
<component>
<component-type>spring.faces.DojoClientNumberValidator</component-type>
<component-class>org.springframework.faces.ui.DojoClientNumberValidator</component-class>
</component>
<component>
<component-type>spring.faces.DojoClientCurrencyValidator</component-type>
<component-class>org.springframework.faces.ui.DojoClientCurrencyValidator</component-class>
</component>
<component>
<component-type>spring.faces.DojoClientNumberValidator</component-type>
<component-class>org.springframework.faces.ui.DojoClientNumberValidator</component-class>
</component>
<component>
<component-type>spring.faces.DojoClientDateValidator</component-type>
<component-class>org.springframework.faces.ui.DojoClientDateValidator</component-class>
</component>
<component>
<component-type>spring.faces.ValidateAll</component-type>
<component-class>org.springframework.faces.ui.DynamicComponent</component-class>
</component>
<render-kit>
<render-kit-id>HTML_BASIC</render-kit-id>
<render-kit-class>org.springframework.faces.webflow.FlowRenderKit</render-kit-class>
<renderer>
<component-family>javax.faces.Command</component-family>
<renderer-type>spring.faces.ProgressiveCommandButtonRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.ProgressiveCommandButtonRenderer</renderer-class>
</renderer>
<renderer>
<component-family>javax.faces.Command</component-family>
<renderer-type>spring.faces.ProgressiveCommandLinkRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.ProgressiveCommandLinkRenderer</renderer-class>
</renderer>
<renderer>
<component-family>javax.faces.Command</component-family>
<renderer-type>spring.faces.AjaxEventInterceptorRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.AjaxEventInterceptorRenderer</renderer-class>
</renderer>
<renderer>
<component-family>spring.faces.Decoration</component-family>
<renderer-type>spring.faces.DojoWidgetRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.DojoWidgetRenderer</renderer-class>
</renderer>
<renderer>
<component-family>spring.faces.DynamicComponent</component-family>
<renderer-type>spring.faces.ValidateAllRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.ValidateAllRenderer</renderer-class>
</renderer>
<renderer>
<component-family>spring.faces.DynamicComponent</component-family>
<renderer-type>spring.faces.DojoStyleRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.DojoStyleRenderer</renderer-class>
</renderer>
<renderer>
<component-family>spring.faces.DynamicComponent</component-family>
<renderer-type>spring.faces.DojoScriptRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.DojoScriptRenderer</renderer-class>
</renderer>
<renderer>
<component-family>spring.faces.DynamicComponent</component-family>
<renderer-type>spring.faces.ResourceGroupRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.ResourceGroupRenderer</renderer-class>
</renderer>
<renderer>
<component-family>spring.faces.DynamicComponent</component-family>
<renderer-type>spring.faces.ResourceRenderer</renderer-type>
<renderer-class>org.springframework.faces.ui.ResourceRenderer</renderer-class>
</renderer>
</render-kit>
</faces-config>

File diff suppressed because it is too large Load Diff

View File

@@ -1,97 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://www.springframework.org/tags/faces</namespace>
<tag>
<tag-name>includeStyles</tag-name>
<component>
<component-type>spring.faces.DojoIncludeStyles</component-type>
<renderer-type>spring.faces.DojoStyleRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>includeScripts</tag-name>
<component>
<component-type>spring.faces.DojoIncludeScripts</component-type>
<renderer-type>spring.faces.DojoScriptRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>resourceGroup</tag-name>
<component>
<component-type>spring.faces.ResourceGroup</component-type>
<renderer-type>spring.faces.ResourceGroupRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>resource</tag-name>
<component>
<component-type>spring.faces.Resource</component-type>
<renderer-type>spring.faces.ResourceRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>commandButton</tag-name>
<component>
<component-type>spring.faces.ProgressiveCommandButton</component-type>
<renderer-type>spring.faces.ProgressiveCommandButtonRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>commandLink</tag-name>
<component>
<component-type>spring.faces.ProgressiveCommandLink</component-type>
<renderer-type>spring.faces.ProgressiveCommandLinkRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>ajaxEvent</tag-name>
<component>
<component-type>spring.faces.AjaxEventInterceptor</component-type>
<renderer-type>spring.faces.AjaxEventInterceptorRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>clientTextValidator</tag-name>
<component>
<component-type>spring.faces.DojoClientTextValidator</component-type>
<renderer-type>spring.faces.DojoWidgetRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>clientNumberValidator</tag-name>
<component>
<component-type>spring.faces.DojoClientNumberValidator</component-type>
<renderer-type>spring.faces.DojoWidgetRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>clientCurrencyValidator</tag-name>
<component>
<component-type>spring.faces.DojoClientCurrencyValidator</component-type>
<renderer-type>spring.faces.DojoWidgetRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>clientDateValidator</tag-name>
<component>
<component-type>spring.faces.DojoClientDateValidator</component-type>
<renderer-type>spring.faces.DojoWidgetRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>validateAllOnClick</tag-name>
<component>
<component-type>spring.faces.ValidateAll</component-type>
<renderer-type>spring.faces.ValidateAllRenderer</renderer-type>
</component>
</tag>
</facelet-taglib>

View File

@@ -1,89 +0,0 @@
package org.springframework.faces.ui;
import java.io.IOException;
import java.io.StringWriter;
import javax.faces.component.UIForm;
import javax.faces.component.UIPanel;
import javax.faces.component.UIViewRoot;
import javax.faces.render.RenderKitFactory;
import junit.framework.TestCase;
import org.apache.myfaces.test.mock.MockResponseWriter;
import org.springframework.faces.webflow.JSFMockHelper;
import org.springframework.faces.webflow.MockViewHandler;
import org.springframework.util.StringUtils;
import org.springframework.webflow.execution.View;
public class AjaxViewRootTests extends TestCase {
JSFMockHelper jsf = new JSFMockHelper();
UIViewRoot testTree = new UIViewRoot();
private final StringWriter output = new StringWriter();
protected void setUp() throws Exception {
this.jsf.setUp();
this.jsf.facesContext().getApplication().setViewHandler(new MockViewHandler());
this.jsf.facesContext().setResponseWriter(new MockResponseWriter(this.output, null, null));
UIForm form = new UIForm();
form.setId("foo");
this.testTree.getChildren().add(form);
UIPanel panel = new UIPanel();
panel.setId("bar");
form.getChildren().add(panel);
ProgressiveUICommand command = new ProgressiveUICommand();
command.setId("baz");
panel.getChildren().add(command);
this.testTree.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
this.jsf.facesContext().setViewRoot(this.testTree);
}
protected void tearDown() throws Exception {
this.jsf.tearDown();
}
public void testProcessDecodes() {
this.jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz");
AjaxViewRoot ajaxRoot = new AjaxViewRoot(this.testTree);
ajaxRoot.processDecodes(this.jsf.facesContext());
assertEquals(1, ajaxRoot.getProcessIds().length);
}
public void testEncodeAll_NoRenderIds() throws IOException {
this.jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz");
AjaxViewRoot ajaxRoot = new AjaxViewRoot(this.testTree);
ajaxRoot.encodeAll(this.jsf.facesContext());
assertEquals(1, ajaxRoot.getProcessIds().length);
assertEquals(1, ajaxRoot.getRenderIds().length);
assertEquals(StringUtils.arrayToCommaDelimitedString(ajaxRoot.getProcessIds()),
StringUtils.arrayToCommaDelimitedString(ajaxRoot.getRenderIds()));
}
public void testEncodeAll_RenderIdsExpr() throws IOException {
this.jsf.externalContext()
.getRequestMap()
.put(View.RENDER_FRAGMENTS_ATTRIBUTE,
StringUtils.delimitedListToStringArray("foo:bar,foo:baz", ",", " "));
AjaxViewRoot ajaxRoot = new AjaxViewRoot(this.testTree);
ajaxRoot.encodeAll(this.jsf.facesContext());
assertEquals(1, ajaxRoot.getRenderIds().length);
assertEquals("foo:bar", StringUtils.arrayToCommaDelimitedString(ajaxRoot.getRenderIds()));
}
}

View File

@@ -1,16 +0,0 @@
package org.springframework.faces.ui;
import junit.framework.TestCase;
public class EscapeQuotesTests extends TestCase {
public final void testEscapeQuotesInLink() {
String linkText = "<a id=\"mainForm:findHotels\" class=\"progressiveLink\" href=\"#\" name=\"mainForm:findHotels\"\\>";
String expectedText = "<a id=\\\"mainForm:findHotels\\\" class=\\\"progressiveLink\\\" href=\\\"#\\\" name=\\\"mainForm:findHotels\\\"\\>";
String result = linkText.replaceAll("\"", "\\\\\"");
System.out.println(linkText);
System.out.println(result);
assertEquals(expectedText, result);
}
}

View File

@@ -1,126 +0,0 @@
package org.springframework.faces.ui;
import javax.faces.component.UIForm;
import javax.faces.component.UIParameter;
import junit.framework.TestCase;
import org.springframework.faces.webflow.JSFMockHelper;
public class ProgressiveCommandLinkRendererTests extends TestCase {
JSFMockHelper jsf = new JSFMockHelper();
ProgressiveCommandLinkRenderer renderer = new ProgressiveCommandLinkRenderer();
public void setUp() throws Exception {
this.jsf.setUp();
}
public void tearDown() throws Exception {
this.jsf.tearDown();
}
public void testRenderOnClick_AjaxEnabled_NoParams() throws Exception {
String expected = "<a onclick=\"Spring.remoting.submitForm(&apos;myForm:foo&apos;, &apos;myForm&apos;, "
+ "{processIds: &apos;myForm:foo&apos;}); return false;\"/>";
UIForm form = new UIForm();
form.setId("myForm");
ProgressiveUICommand link = new ProgressiveUICommand();
link.setId("foo");
form.getChildren().add(link);
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
this.jsf.facesContext().getResponseWriter().startElement("a", link);
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
this.jsf.facesContext().getResponseWriter().endElement("a");
assertEquals(expected, this.jsf.contentAsString());
}
public void testRenderOnClick_AjaxEnabled_WithParams() throws Exception {
String expected = "<a onclick=\"Spring.remoting.submitForm(&apos;myForm:foo&apos;, &apos;myForm&apos;, "
+ "{processIds: &apos;myForm:foo&apos;, foo : &apos;bar&apos;, zoo : &apos;baz&apos;}"
+ "); return false;\"/>";
UIForm form = new UIForm();
form.setId("myForm");
ProgressiveUICommand link = new ProgressiveUICommand();
link.setId("foo");
form.getChildren().add(link);
UIParameter param1 = new UIParameter();
param1.setName("foo");
param1.setValue("bar");
UIParameter param2 = new UIParameter();
param2.setName("zoo");
param2.setValue("baz");
link.getChildren().add(param1);
link.getChildren().add(param2);
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
this.jsf.facesContext().getResponseWriter().startElement("a", link);
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
this.jsf.facesContext().getResponseWriter().endElement("a");
assertEquals(expected, this.jsf.contentAsString());
}
public void testRenderOnClick_AjaxDisabled_NoParams() throws Exception {
String expected = "<a onclick=\"this.submitFormFromLink(&apos;myForm&apos;,&apos;myForm:foo&apos;, []); return false;\"/>";
UIForm form = new UIForm();
form.setId("myForm");
ProgressiveUICommand link = new ProgressiveUICommand();
link.setId("foo");
link.setAjaxEnabled(false);
form.getChildren().add(link);
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
this.jsf.facesContext().getResponseWriter().startElement("a", link);
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
this.jsf.facesContext().getResponseWriter().endElement("a");
assertEquals(expected, this.jsf.contentAsString());
}
public void testRenderOnClick_AjaxDisabled_WithParams() throws Exception {
String expected = "<a onclick=\"this.submitFormFromLink(&apos;myForm&apos;,&apos;myForm:foo&apos;, ["
+ "{name : &apos;foo&apos;, value : &apos;bar&apos;}, {name : &apos;zoo&apos;, value : &apos;baz&apos;}"
+ "]); return false;\"/>";
UIForm form = new UIForm();
form.setId("myForm");
ProgressiveUICommand link = new ProgressiveUICommand();
link.setId("foo");
link.setAjaxEnabled(false);
form.getChildren().add(link);
UIParameter param1 = new UIParameter();
param1.setName("foo");
param1.setValue("bar");
UIParameter param2 = new UIParameter();
param2.setName("zoo");
param2.setValue("baz");
link.getChildren().add(param1);
link.getChildren().add(param2);
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
this.jsf.facesContext().getResponseWriter().startElement("a", link);
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
this.jsf.facesContext().getResponseWriter().endElement("a");
assertEquals(expected, this.jsf.contentAsString());
}
}

View File

@@ -1,19 +0,0 @@
package org.springframework.faces.ui;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
public class TestConverter implements Converter {
public TestConverter() {
}
public Object getAsObject(FacesContext context, UIComponent component, String value) {
throw new UnsupportedOperationException();
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
return ((TestValue) value).getStringValue();
}
}

View File

@@ -1,8 +0,0 @@
package org.springframework.faces.ui;
public class TestValue {
public String getStringValue() {
return "foo";
}
}

View File

@@ -1,53 +0,0 @@
package org.springframework.faces.ui.resource;
import java.io.IOException;
import java.io.StringWriter;
import junit.framework.TestCase;
import org.apache.myfaces.test.mock.MockResponseWriter;
import org.springframework.faces.webflow.JSFMockHelper;
public class FlowResourceHelperTests extends TestCase {
StringWriter writer = new StringWriter();
JSFMockHelper jsf = new JSFMockHelper();
protected void setUp() throws Exception {
this.jsf.setUp();
// TODO figure out how to set the context path
this.jsf.facesContext().setResponseWriter(new MockResponseWriter(this.writer, "text/html", "UTF-8"));
}
protected void tearDown() throws Exception {
this.jsf.tearDown();
}
public final void testRenderScriptLink() throws IOException {
String scriptPath = "/dojo/dojo.js";
String expectedUrl = "null/resources/dojo/dojo.js";
ResourceHelper.renderScriptLink(this.jsf.facesContext(), scriptPath);
ResourceHelper.renderScriptLink(this.jsf.facesContext(), scriptPath);
String expectedOutput = "<script type=\"text/javascript\" src=\"" + expectedUrl + "\"/>";
assertEquals(expectedOutput, this.writer.toString());
}
public final void testRenderStyleLink() throws IOException {
String scriptPath = "/dijit/themes/dijit.css";
String expectedUrl = "null/resources/dijit/themes/dijit.css";
ResourceHelper.renderStyleLink(this.jsf.facesContext(), scriptPath);
ResourceHelper.renderStyleLink(this.jsf.facesContext(), scriptPath);
String expectedOutput = "<link type=\"text/css\" rel=\"stylesheet\" href=\"" + expectedUrl + "\"/>";
assertEquals(expectedOutput, this.writer.toString());
}
}

View File

@@ -17,7 +17,6 @@ import junit.framework.TestCase;
import org.apache.myfaces.test.mock.MockResponseWriter;
import org.apache.myfaces.test.mock.MockStateManager;
import org.easymock.EasyMock;
import org.springframework.faces.ui.AjaxViewRoot;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.execution.FlowExecutionContext;
import org.springframework.webflow.execution.FlowExecutionKey;
@@ -104,12 +103,6 @@ public class JsfViewTests extends TestCase {
this.view.saveState();
}
public final void testSaveState_AjaxViewRoot() {
EasyMock.replay(new Object[] { this.context, this.flowExecutionContext, this.flowMap, this.flashScope });
this.view.setViewRoot(new AjaxViewRoot(this.view.getViewRoot()));
this.view.saveState();
}
public final void testRender() throws IOException {
EasyMock.expect(this.flashScope.put(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY), EasyMock.anyObject()))
@@ -160,33 +153,6 @@ public class JsfViewTests extends TestCase {
assertTrue("The lifecycle should have been invoked", ((NoEventLifecycle) lifecycle).executed);
}
/**
* Ajax Request - View already exists in view scope and must be restored and the lifecycle executed, no event
* signaled
*/
public final void testProcessUserEvent_Restored_Ajax_NoEvent() {
EasyMock.expect(this.flashScope.getBoolean(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY))).andStubReturn(
false);
EasyMock.expect(this.flashScope.put(EasyMock.matches(FlowFacesContext.RENDER_RESPONSE_KEY), EasyMock.anyObject()))
.andStubReturn(null);
Lifecycle lifecycle = new NoEventLifecycle(this.jsfMock.lifecycle());
UIViewRoot existingRoot = new UIViewRoot();
existingRoot.setViewId(VIEW_ID);
AjaxViewRoot ajaxRoot = new AjaxViewRoot(existingRoot);
EasyMock.replay(new Object[] { this.context, this.flowExecutionContext, this.flowMap, this.flashScope });
JsfView restoredView = new JsfView(ajaxRoot, lifecycle, this.context);
restoredView.processUserEvent();
assertFalse("An unexpected event was signaled,", restoredView.hasFlowEvent());
assertTrue("The lifecycle should have been invoked", ((NoEventLifecycle) lifecycle).executed);
}
/**
* View already exists in view scope and must be restored and the lifecycle executed, an event is signaled
*/