/* * � 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; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter; import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; import org.w3c.dom.Node; import com.ibm.commons.util.StringUtil; import com.ibm.designer.domino.xsp.api.panels.XPagesAVFolder; import com.ibm.designer.domino.xsp.api.panels.XPagesAVPage; import com.ibm.designer.domino.xsp.api.panels.XPagesAttributesProvider; import com.ibm.designer.domino.xsp.api.util.XPagesKey; import com.ibm.xsp.extlib.designer.tooling.utils.ExtLibToolingLogger; @SuppressWarnings("restriction") // $NON-NLS-1$ abstract public class DynamicAttributesProvider extends XPagesAttributesProvider { protected boolean _needToRebuild = false; protected Set<INodeNotifier> _nodesListenedTo = new HashSet<INodeNotifier>(); protected static String DATA_CATEGORY_OBJECT = "propprovcat"; //$NON-NLS-1$ INodeAdapter _listener = new INodeAdapter() { public boolean isAdapterForType(Object type) { return type instanceof DynamicAttributesProvider; } /** * INodeNotifier.ADD, REMOVE, CHANGE, STRUCTURE_CHANGED, CONTENT_CHANGED */ public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) { if (shouldRebuildTabs(notifier, eventType, changedFeature, oldValue, newValue, pos)) { setRebuild(); } } }; abstract protected boolean shouldRebuildTabs(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos); abstract protected String getExtensionTagName(XPagesKey key); abstract protected Set<INodeNotifier> getNodeNotifiers(Node node); private void setRebuild() { Node node = getNode(); if (null != node) { node.setUserData(DATA_CATEGORY_OBJECT, new Object(), null); } _needToRebuild = true; } /* (non-Javadoc) * @see com.ibm.designer.domino.xsp.api.panels.XPagesAttributesProvider#getCategoryID() */ @Override public String getCategoryID() { Node node = getNode(); if (null != node) { Object o = node.getUserData(DATA_CATEGORY_OBJECT); if (null != o) return String.valueOf(o.hashCode()); } if (_needToRebuild) { removeNodeListeners(); _needToRebuild = false; } return super.getCategoryID(); } /* (non-Javadoc) * @see com.ibm.designer.domino.xsp.api.panels.XPagesAttributesProvider#doGetAVPagesForTag(com.ibm.designer.domino.xsp.api.util.XPagesKey, com.ibm.designer.domino.xsp.api.panels.XPagesAVFolder) */ @Override protected XPagesAVPage[] doGetAVPagesForTag(XPagesKey key, XPagesAVFolder folder) { setupNodeAdapters(); XPagesAVPage[] av = null; try { String keyname = getExtensionTagName(key); if (StringUtil.isNotEmpty(keyname)) { XPagesKey otherKey = new XPagesKey(key.getNamespaceUri(), keyname); av = super.doGetAVPagesForTag(otherKey, folder); } } catch(Exception e) { ExtLibToolingLogger.EXT_LIB_TOOLING_LOGGER.error(e, e.toString()); } if (av == null || av.length == 0) av = super.doGetAVPagesForTag(key, folder); return av; } private void setupNodeAdapters() { Set<INodeNotifier> set = getNodeNotifiers(getNode()); if (null == set) return; for (Iterator<INodeNotifier> it = set.iterator(); it.hasNext();) { addNodeAdapter(it.next()); } } protected void addNodeAdapter(INodeNotifier nn) { INodeAdapter na = nn.getAdapterFor(this); if (na != null) { ExtLibToolingLogger.EXT_LIB_TOOLING_LOGGER.traceDebugp(this.getClass(), "addNodeAdapter", "already has a noe listsner"); //$NON-NLS-1$ //$NON-NLS-2$ nn.removeAdapter(na); } nn.addAdapter(_listener); _nodesListenedTo.add(nn); } private void removeNodeListeners() { for (Iterator<INodeNotifier> it = _nodesListenedTo.iterator(); it.hasNext();) { INodeNotifier nn = it.next(); nn.removeAdapter(_listener); } _nodesListenedTo.clear(); } }