/******************************************************************************* * Copyright (c) 2001, 2007 Oracle Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Oracle Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jst.pagedesigner.itemcreation; import org.eclipse.jst.jsf.core.internal.tld.ITLDConstants; import org.eclipse.jst.pagedesigner.dom.IDOMPosition; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement; import org.w3c.dom.Element; /** * The abstract class from which all client ITagCreator instances * should be derived. * * The createTag method enforces a set of steps required by the framework * to create a new tag. However, it allows you to configure some of the steps * by providing an ITagCreationAdvisor through the doSelectCreationAdvisor. * * <p><b>Provisional API - subject to change</b></p> * * @author cbateman * */ public abstract class AbstractTagCreator implements ITagCreator { /* (non-Javadoc) * @see org.eclipse.jst.pagedesigner.itemcreation.ITagCreator#createTag(org.eclipse.jst.pagedesigner.editors.palette.TagToolPaletteEntry, org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel, org.eclipse.jst.pagedesigner.dom.IDOMPosition) */ public final Element createTag(final CreationData creationData) { final ITagCreationAdvisor advisor = selectCreationAdvisor(creationData); // adjust the creation position to accommodate required containers final IDOMPosition position = advisor.checkAndApplyNecessaryContainers(creationData.getModel(), creationData.getDomPosition()); if (position == null) return null;//throw exception? creationData.setAdjustedPosition(position); // create the element final Element ele = createElement(creationData); if (ele == null) return null;//throw exception? // apply tag customization advisor.applyCustomization(creationData.getModel(), ele); // ensure that any attributes required by the tag's definition // is initialized. // TODO: a drawback of this approach is that it leaves the tag in // a state where there are no error flags to tell the user something is // missing, but may initialize the tag with an (empty) invalid value //ensureRequiredAttrs(ele, creationData); addTagToContainer(position, ele); return ele; } private ITagCreationAdvisor selectCreationAdvisor(CreationData creationData) { ITagCreationAdvisor advisor = doSelectCreationAdvisor(creationData); // enforce that the advisor must be an AbstractTagCreationAdvisor to // avoid using the default (not this case also covers advisor == null) if (! (advisor instanceof AbstractTagCreationAdvisor)) { advisor = new DefaultTagCreationAdvisor(creationData); } return advisor; } /** * @param creationData * @return a tag creation advisor or null to indicate the use of the system default */ protected abstract ITagCreationAdvisor doSelectCreationAdvisor(CreationData creationData); /** * @param creationData * @return {@link Element} */ protected final Element createElement(final CreationData creationData) { Element ele = creationData.getModel().getDocument().createElement(creationData.getTagName()); if (ele == null) return null; //ugly... fix me // TODO: move this into an ensure method? // XXX: we are using "startsWith("directive.")" to test whether // should setJSPTag, this // maybe is not the best way. Need check whether SSE have special // API for it. if (ITLDConstants.URI_JSP.equals(creationData.getUri()) && (ele.getLocalName().startsWith("directive.") //$NON-NLS-1$ || "declaration".equals(ele.getLocalName()) //$NON-NLS-1$ || "expression".equals(ele.getLocalName()) || "scriptlet" //$NON-NLS-1$ //$NON-NLS-2$ .equals(ele.getLocalName()))) { // it is a jsp tag ((IDOMElement) ele).setJSPTag(true); } if (creationData.getPrefix() != null) { ele.setPrefix(creationData.getPrefix()); } return ele; } /** * @param position * @param tagElement */ private void addTagToContainer(final IDOMPosition position, final Element tagElement) { if (position == null || position.getContainerNode() == null) { return; } if (position.getNextSiblingNode() == null) { position.getContainerNode().appendChild(tagElement); } else { position.getContainerNode().insertBefore(tagElement, position.getNextSiblingNode()); } } }