Skip to content
This repository was archived by the owner on Jan 21, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ private EncodedOutputStream getEncodedOutputStream() throws IOException{

/**
* Inner class EncodedOutputStream used to support encodings like gzip and deflate.
* Cache is require to emit the Conent-Length and used to support persistent connections.
* Cache is require to emit the Content-Length and used to support persistent connections.
**/
private static class EncodedOutputStream extends ServletOutputStream {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright IBM Corp. 2010
* © Copyright IBM Corp. 2010
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,8 +16,24 @@
dojo.provide("extlib.dijit.DynamicContent");

XSP.showContent = function xe_sct(panelid,content,params) {
params = dojo.mixin(params,{content:content})
if(XSP._hashContentId==panelid) {
params = dojo.mixin(params, dojo.queryToObject(dojo.hash()));

var mixParams = {};
var elem = dojo.byId(panelid);
var contentParam = "content";
if(elem != null) {
var elemContentParam = elem.getAttribute("data-param");
if(elemContentParam) {
contentParam = elemContentParam;
}
}
mixParams[contentParam] = content;

params = dojo.mixin(params,mixParams)
// If the param is set up for useHash, update the hash as well.
// This doesn't check the id property in order to maintain consistency with
// previous behavior.
if(XSP._hashContent && XSP._hashContent[contentParam]) {
XSP.updateHash(dojo.objectToQuery(params))
XSP.partialRefreshGet(panelid,{params:XSP._hash})
} else {
Expand All @@ -26,14 +42,48 @@ XSP.showContent = function xe_sct(panelid,content,params) {
}

XSP.registerHash = function xe_rhs(panelid) {
XSP._hashContentId=panelid
if(!XSP._hashContent) {
XSP._hashContent = {};
}

var elem = dojo.byId(panelid);
if(!elem) { return; }
var contentParam = elem.getAttribute("data-param");

if(!XSP._hashContent[contentParam]) {
XSP._hashContent[contentParam] = {
id: panelid,
value: ""
};
}

if(!XSP._hashCallback) {
dojo.require("dojo.hash");
XSP._hashCallback = function(hash) {
// Only refresh if the has is different from the last one
if(XSP._hash!=hash) {
XSP._hash=hash
XSP.partialRefreshGet(XSP._hashContentId,{params:hash})
var hashObj = dojo.queryToObject(hash);
var refreshIds = [];
for(var paramName in hashObj) {
// Only refresh if the hash is different from the last one for that panel
if(XSP._hashContent[paramName] && XSP._hashContent[paramName].value != hashObj[paramName]) {
refreshIds.push(XSP._hashContent[paramName].id);
XSP._hashContent[paramName].value = hashObj[paramName];
}
}

// Cycle through IDs needing an update in sequence
if(refreshIds.length > 0) {
XSP._hash=hash;

var refresh = function() {
var id = refreshIds.pop();
if(id) {
XSP.partialRefreshGet(id, {
params: hash,
onComplete: refresh
});
}
}
refresh();
}
}
dojo.addOnLoad( function() {
Expand All @@ -47,6 +97,16 @@ XSP.registerHash = function xe_rhs(panelid) {

// Update the copy of the hash while preventing the event processing
XSP.updateHash = function xs_uhs(h) {
// Split it apart to update only the specific part of the hash
var updateObj = dojo.queryToObject(h);
var hashObj = dojo.queryToObject(dojo.hash());

for(var updateKey in updateObj) {
hashObj[updateKey] = updateObj[updateKey];
}

h = dojo.objectToQuery(hashObj);

XSP._hash=h
dojo.hash(h)
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@
*/
public class UIDynamicContent extends UIDynamicControl {

public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.DynamicContent"; // $NON-NLS-1$
public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.DynamicContent"; //$NON-NLS-1$
public static final String RENDERER_TYPE = "com.ibm.xsp.extlib.dynamiccontent.DynamicContent"; //$NON-NLS-1$


public static final String XSPCONTENT_PARAM = "content"; // $NON-NLS-1$
public static final String PSEUDO_FACET_EMPTY = "-empty-"; // $NON-NLS-1$
public static final String PSEUDO_FACET_CHILDREN = "-children-"; // $NON-NLS-1$
public static final String PSEUDO_FACET_DEFAULT = "-default-"; // $NON-NLS-1$
public static final String PSEUDO_FACET_EMPTY = "-empty-"; //$NON-NLS-1$
public static final String PSEUDO_FACET_CHILDREN = "-children-"; //$NON-NLS-1$
public static final String PSEUDO_FACET_DEFAULT = "-default-"; //$NON-NLS-1$

private Boolean partialEvents;
private Boolean useHash;
private String defaultFacet;
private String contentParam;
// The currently displayed facet, not a property in the All Properties.
// This does not vary for different clientIds, as it reflects the
// structure of the UIComponent tree.
Expand Down Expand Up @@ -140,6 +140,27 @@ public void setDefaultFacet(String defaultFacet) {
this.defaultFacet = defaultFacet;
}

/**
* @return the user-specified content parameter name, if specified and non-empty, or
* {@link UIDynamicControl#XSPCONTENT_PARAM} otherwise
*/
@Override
public String getContentParam() {
if(StringUtil.isNotEmpty(this.contentParam)) {
return this.contentParam;
}
ValueBinding _vb = getValueBinding("defaultFacet"); //$NON-NLS-1$
if(_vb != null) {
return (String)_vb.getValue(getFacesContext());
} else {
return XSPCONTENT_PARAM;
}
}

public void setContentParam(String contentParam) {
this.contentParam = contentParam;
}


@Override
public MethodBinding getBeforeContentLoad() {
Expand Down Expand Up @@ -197,7 +218,7 @@ public void show(String facet, Map<String,String> parameters) {
// facet is non-empty here
if( !StringUtil.equals(PSEUDO_FACET_EMPTY, facet) ) {
pushParameters(context, parameters);
TypedUtil.getRequestMap(context.getExternalContext()).put(XSPCONTENT_PARAM,facet);
TypedUtil.getRequestMap(context.getExternalContext()).put(getContentParam(),facet);
createContent(context);
} else {
deleteContent(context);
Expand All @@ -210,15 +231,15 @@ protected void updateHash(String facet, Map<String,String> parameters) {
StringBuilder b = new StringBuilder();
if(StringUtil.isNotEmpty(facet)) {
try {
b.append(XSPCONTENT_PARAM);
b.append(getContentParam());
b.append('=');
b.append(URLEncoder.encode(facet,"UTF-8")); // $NON-NLS-1$
b.append(URLEncoder.encode(facet,"UTF-8")); //$NON-NLS-1$
if(parameters!=null) {
for(Map.Entry<String, String> e: parameters.entrySet()) {
b.append('&');
b.append(URLEncoder.encode(e.getKey().toString(), "UTF-8")); // $NON-NLS-1$
b.append(URLEncoder.encode(e.getKey().toString(), "UTF-8")); //$NON-NLS-1$
b.append('=');
b.append(URLEncoder.encode(e.getValue().toString(),"UTF-8")); // $NON-NLS-1$
b.append(URLEncoder.encode(e.getValue().toString(),"UTF-8")); //$NON-NLS-1$
}
}
} catch(UnsupportedEncodingException ex) {}
Expand Down Expand Up @@ -250,7 +271,7 @@ public boolean isCreateRequest(FacesContextEx ctx) {
String id = ctx.getPartialRefreshId();
if(StringUtil.equals(id, getClientId(ctx))) {
// We should check that this is the initial request
String xspContent = (String)ctx.getExternalContext().getRequestParameterMap().get(XSPCONTENT_PARAM);
String xspContent = (String)ctx.getExternalContext().getRequestParameterMap().get(getContentParam());
return StringUtil.isNotEmpty(xspContent);
}
}
Expand Down Expand Up @@ -285,7 +306,7 @@ public void buildDefaultContents(FacesContext context, FacesComponentBuilder bui
@Override
protected void buildDynamicContents(FacesContext context, FacesComponentBuilder builder) throws FacesException {
// Build the facet if passed as a parameter
String xspFacet = ExtLibUtil.readParameter(context,XSPCONTENT_PARAM);
String xspFacet = ExtLibUtil.readParameter(context,getContentParam());
// the pseudo-facet will have been pre-processed by the show(..) method,
// so it will not be "", -empty- or -default-, but it may still be -children-
buildFacet(context, builder, xspFacet);
Expand Down Expand Up @@ -354,18 +375,20 @@ public void restoreState(FacesContext _context, Object _state) {
currentFacet = (String)_values[4];
beforeContentLoad = StateHolderUtil.restoreMethodBinding(_context, this, _values[5]);
afterContentLoad = StateHolderUtil.restoreMethodBinding(_context, this, _values[6]);
contentParam = (String)_values[7];
}

@Override
public Object saveState(FacesContext _context) {
Object _values[] = new Object[7];
Object _values[] = new Object[8];
_values[0] = super.saveState(_context);
_values[1] = partialEvents;
_values[2] = useHash;
_values[3] = defaultFacet;
_values[4] = currentFacet;
_values[5] = StateHolderUtil.saveMethodBinding(_context, beforeContentLoad);
_values[6] = StateHolderUtil.saveMethodBinding(_context, afterContentLoad);
_values[7] = contentParam;
return _values;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ public abstract class UIDynamicControl extends AbstractDynamicContent implements
// the execId control to be a NamingContainer, and otherwise will not validate
// the content of that control.

public static final String COMPONENT_FAMILY = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; // $NON-NLS-1$
public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; // $NON-NLS-1$
public static final String COMPONENT_FAMILY = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; //$NON-NLS-1$
public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; //$NON-NLS-1$


public static final String XSPCONTENT_PARAM = "content"; //$NON-NLS-1$

// FacesDynamicContainer
private String sourcePageName;
Expand All @@ -69,6 +72,10 @@ public boolean isAutoCreate() {
public String getFamily() {
return COMPONENT_FAMILY;
}

public String getContentParam() {
return XSPCONTENT_PARAM;
}


// ========================================================
Expand Down Expand Up @@ -99,7 +106,7 @@ public void buildContents(FacesContext context, FacesComponentBuilder builder) t
//[dc] If the content parameter is present as parameter that means the URL was of the form http://my.web/myxsp.xsp?content=key
// in this case we build the actual "key" facet, so the whole page with the correct content will be returned to the client.
// This is needed when a web crawler visit the page following the link.
String xspFacet = ExtLibUtil.readParameter(context,UIDynamicContent.XSPCONTENT_PARAM);
String xspFacet = ExtLibUtil.readParameter(context,getContentParam());
if(xspFacet != null && builder.isFacetAvailable(context, this, xspFacet)) {
buildDynamicContents(context, builder);
}else {
Expand Down Expand Up @@ -129,6 +136,7 @@ protected void buildDynamicContents(FacesContext context, FacesComponentBuilder
// FacesDynamicContainer implementation
// ========================================================

@Override
public String getSourcePageName() {
return sourcePageName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@
</designer-extension>
</property-extension>
</property>
<property>
<description>%property.contentParam.component.dynamicContent.descr%</description>
<display-name>%property.contentParam.component.dynamicContent.name%</display-name>
<property-name>contentParam</property-name>
<property-class>java.lang.String</property-class>
<property-extension>
<designer-extension>
<category>basics</category>
<tags>
todo
</tags>
</designer-extension>
</property-extension>
</property>
<property>
<description>%property.defaultFacet.component.dynamicContent.descr%</description>
<display-name>%property.defaultFacet.component.dynamicContent.name%</display-name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ property.for.complex-type.inPlaceFormAction.name= For
property.for.complex-type.inPlaceFormAction.descr= ID of the In Place Form control whose state will be changed by this action. If empty, it uses the closest In Place Form Control in the parent hierarchy.
property.formAction.name= Form Action
property.formAction.descr= The Action to perform on the In Place Form: show, hide or toggle.
property.contentParam.component.dynamicContent.name= Content Parameter Name
property.contentParam.component.dynamicContent.descr= The URL/hash parameter name to use when determining the current facet. If empty, it defaults to "content".
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,8 @@
</property-extension>
</property>
<property>
<!-- TODO better description of what this means - and include the # symbol in the description
as the word hash is european - it's known as pound in the USA,
explain that it isn't just #facetName, it's #value=facetName
which is weird actually - maybe should configure that? -->
<description>Indicate that the control should manage its state using a URL hash, that is some text after a "#" symbol in the URL, like: /page1.xsp#detail</description>
<!-- TODO better description of what this means -->
<description>Indicate that the control should manage its state using a URL hash, that is some text after a "#" symbol in the URL, like: /page1.xsp#content=detail</description>
<display-name>Use URL Hash</display-name>
<property-name>useHash</property-name>
<property-class>boolean</property-class>
Expand Down Expand Up @@ -235,6 +232,20 @@
</designer-extension>
</property-extension>
</property>
<property>
<description>The URL/hash parameter name to use when determining the current facet. If empty, it defaults to "content".</description>
<display-name>Content Parameter Name</display-name>
<property-name>contentParam</property-name>
<property-class>java.lang.String</property-class>
<property-extension>
<designer-extension>
<category>basics</category>
<tags>
todo
</tags>
</designer-extension>
</property-extension>
</property>

<component-extension>
<base-component-type>com.ibm.xsp.extlib.dynamiccontent.Dynamic</base-component-type>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.component.UIViewRootEx;
import com.ibm.xsp.extlib.component.dynamiccontent.AbstractDynamicContent;
import com.ibm.xsp.extlib.component.dynamiccontent.UIDynamicControl;
import com.ibm.xsp.extlib.controls.ExtlibControlsLogger;
import com.ibm.xsp.extlib.renderkit.html_extended.FacesRendererEx;
import com.ibm.xsp.resource.Resource;
Expand All @@ -50,6 +51,10 @@ public void encodeBegin(FacesContext context, UIComponent component)
w.writeAttribute("id", clientId, "id"); // $NON-NLS-1$ $NON-NLS-2$
//w.writeAttribute("style", "display: none", "style");

if(component instanceof UIDynamicControl) {
w.writeAttribute("data-param", ((UIDynamicControl) component).getContentParam(), null); //$NON-NLS-1$
}

// Add the newly added resources, if some
if(AbstractDynamicContent.USE_DYNAMIC_RESOURCES) {
Integer rc = (Integer)context.getExternalContext().getRequestMap().get(AbstractDynamicContent.DYNAMIC_RESOURCES);
Expand Down