/*
* � Copyright IBM Corp. 2011
*
* 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 com.ibm.xsp.extlib.designer.tooling.panels.applicationlayout;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.ibm.commons.iloader.node.DataChangeNotifier;
import com.ibm.commons.iloader.node.DataNode;
import com.ibm.commons.iloader.node.IMember;
import com.ibm.commons.iloader.node.NodeException;
import com.ibm.commons.util.StringUtil;
import com.ibm.commons.xml.DOMUtil;
import com.ibm.designer.domino.xsp.api.util.XPagesDOMUtil;
import com.ibm.xsp.extlib.designer.tooling.constants.IExtLibAttrNames;
import com.ibm.xsp.extlib.designer.tooling.utils.ComputedFieldVetoHandler;
import com.ibm.xsp.registry.FacesRegistry;
/**
* @author mblout
*
*/
@SuppressWarnings("restriction")//$NON-NLS-1$
public class CallbackComputedField extends DataNode.ComputedField {
public interface SetHandler {
boolean shouldSet(CallbackComputedField cf, Object instance, String value, DataChangeNotifier notifier);
void updateControl(CallbackComputedField cf);
}
public final static String XSP_TAG_THIS_FACETS = "this.facets"; //$NON-NLS-1$
public final static String XSP_TAG_CALLBACK = "callback"; //$NON-NLS-1$
public final static String XSP_ATTR_FACET_KEY = "xp:key"; //$NON-NLS-1$
public final static String XSP_ATTR_FACETNAME = "facetName"; //$NON-NLS-1$
public final static String XSP_ATTR_ID = IExtLibAttrNames.EXT_LIB_ATTR_ID;
private final FacesRegistry registry;
private final boolean hasName;
private final String key;
private ComputedFieldVetoHandler vetohandler;
public CallbackComputedField(String name, String key, boolean hasName, FacesRegistry registry) {
super(name, IMember.TYPE_BOOLEAN);
this.registry = registry;
this.hasName = hasName;
this.key = key;
}
public boolean hasName() {
return hasName;
}
public boolean isReadOnly() {
return false;
}
public void setVetoHandler(ComputedFieldVetoHandler vetohandler) {
this.vetohandler = vetohandler;
}
public String getValue(Object instance) throws NodeException {
Element e = (Element) instance;
if (hasName) {
e = getFacets(e);
}
if (null != e) {
Element element = getCallback(e, getName());
if (element != null) {
// String name = element.getAttribute(XSP_ATTR_FACETNAME);
// if(StringUtil.isNotEmpty(name)){
// return name;
// }
return Boolean.toString(true);
}
}
return null;
}
public void setValue(Object instance, String value, DataChangeNotifier notifier) throws NodeException {
if (null != vetohandler) {
if (!vetohandler.checkShouldSet(this, instance, value, notifier)) {
return;
}
}
Element e = (Element) instance;
boolean remove = StringUtil.isEmpty(value) || StringUtil.isFalseValue(value);
if (remove) {
if (hasName) {
e = getFacets(e);
}
if (null != e) {
Element cb = getCallback(e, getName());
if (null != cb) {
Node parent = cb.getParentNode();
if (parent instanceof INodeNotifier) {
INodeNotifier nn = (INodeNotifier)parent;
INodeAdapter a = nn.getAdapterFor(cb);
if (null != a)
nn.removeAdapter(a);
}
if (cb instanceof INodeNotifier) {
INodeNotifier nn = (INodeNotifier)cb;
INodeAdapter a = nn.getAdapterFor(CallbackComputedField.class);
if (null != a)
nn.removeAdapter(a);
}
e.removeChild(cb);
}
}
}
else { // !remove (value is 'true')
if (hasName) {
e = getOrCreateFacets(e, registry);
}
if (null != e) {
Element cb = getOrCreateCallback(e, getName(), registry);
cb.setAttribute(XSP_ATTR_ID, getName());
if (StringUtil.isNotEmpty(key)) {
cb.setAttribute(XSP_ATTR_FACET_KEY, key);
}
}
}
XPagesDOMUtil.formatNode(e, null);
}
// public boolean shouldRecompute(Object instance, Object object, int operation, IMember member, int position) {
// return false;
// }
public static Element getFacets(Element parent) {
NodeList facetsNodeList = DOMUtil.getChildElementsByTagNameNS(parent, parent.getNamespaceURI(), XSP_TAG_THIS_FACETS);
return (Element) facetsNodeList.item(0);
}
public static Element getCallback(Element parent, String name) {
NodeList nodeList = DOMUtil.getChildElementsByTagNameNS(parent, XPagesDOMUtil.getNamespaceUri(), XSP_TAG_CALLBACK);
for (int i = 0; i < nodeList.getLength(); i++) {
Node n = nodeList.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE) {
Element e = (Element)n;
String s = e.getAttribute(XSP_ATTR_FACETNAME);
if (StringUtil.equals(name, s))
return e;
}
}
return null;
}
// facets should have the same namespace as their parent
public static Element getOrCreateFacets(Element parent, FacesRegistry registry) {
// if facet doesn't exist, create it, and also return it.
Element facets = getFacets(parent);
if (facets == null) {
facets = XPagesDOMUtil.createElement(parent.getOwnerDocument(), registry, parent.getNamespaceURI(),
XSP_TAG_THIS_FACETS);
parent.insertBefore(facets, parent.getFirstChild());
}
return facets;
}
public static Element getOrCreateCallback(Element parent, String name, FacesRegistry registry) {
Element cb = getCallback(parent, name);
if (cb == null) {
cb = XPagesDOMUtil.createElement(parent.getOwnerDocument(), registry, XPagesDOMUtil.getNamespaceUri(), XSP_TAG_CALLBACK);
if (null != name) {
cb.setAttribute(XSP_ATTR_FACETNAME, name);
}
parent.insertBefore(cb, parent.getFirstChild());
}
return cb;
}
}