Package org.eclipse.jst.pagedesigner.dtmanager.converter.internal

Source Code of org.eclipse.jst.pagedesigner.dtmanager.converter.internal.DTTagConverterDecorator

/*******************************************************************************
* Copyright (c) 2005 Oracle Corporation.
* 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.dtmanager.converter.internal;

import java.net.URL;

import javax.servlet.jsp.el.ELException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.internal.IImageDescriptorProvider;
import org.eclipse.jst.jsf.common.metadata.internal.IMetaDataSourceModelProvider;
import org.eclipse.jst.jsf.common.metadata.internal.IResourceURLProvider;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
import org.eclipse.jst.pagedesigner.converter.ITagConverter;
import org.eclipse.jst.pagedesigner.dtmanager.DTManager;
import org.eclipse.jst.pagedesigner.dtmanager.IDTInfo;
import org.eclipse.jst.pagedesigner.dtmanager.converter.ITagConverterDecorator;
import org.eclipse.jst.pagedesigner.dtmanager.dtinfo.ResolveAttributeValue;
import org.eclipse.jst.pagedesigner.dtmanager.dtinfo.TagDecorateInfo;
import org.eclipse.jst.pagedesigner.preview.PageExpressionContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
* ITagConverterDecorator implementation for DTTagConverter.
*
* @author Ian Trimble - Oracle
*/
public class DTTagConverterDecorator implements ITagConverterDecorator
{

    private static final String DECORATE_INFO_ID_DESIGN = "vpd-decorate-design"; //$NON-NLS-1$
    private static final String DECORATE_INFO_ID_PREVIEW = "vpd-decorate-preview"; //$NON-NLS-1$
    private static final String MD_PLUGIN_LOCATION = "$metadata-plugin-location$"; //$NON-NLS-1$

    /*
     * (non-Javadoc)
     *
     * @see
     * org.eclipse.jst.pagedesigner.dtmanager.converter.ITagConverterDecorator
     * #decorate(org.eclipse.jst.pagedesigner.converter.ITagConverter)
     */
    public void decorate(ITagConverter tagConverter)
    {
        if (!(tagConverter instanceof DTTagConverter))
        {
            throw new IllegalArgumentException(
                    "ITagConverter argument must be an instance of DTTagConverter"); //$NON-NLS-1$
        }
        DTTagConverter dtTagConverter = (DTTagConverter) tagConverter;

        if (dtTagConverter.getMode() == IConverterFactory.MODE_DESIGNER)
        {
            decorateFromDTInfo(dtTagConverter, DECORATE_INFO_ID_DESIGN);
        } else if (dtTagConverter.getMode() == IConverterFactory.MODE_PREVIEW)
        {
            decorateFromDTInfo(dtTagConverter, DECORATE_INFO_ID_PREVIEW);
        }

        if (tagConverter.getResultElement() == null
                && tagConverter.isVisualByHTML())
        {
            createUnknownTagRepresentation(dtTagConverter);
        }
    }

    /**
     * Performs decoration of the specified DTTagConverter instance from IDTInfo
     * (metadata) for the specified (by ID) TagDecorateInfo.
     *
     * @param dtTagConverter
     *            DTTagConverter instance.
     * @param tagDecorateInfoID
     *            ID of the TagDecorateInfo to be located in metadata.
     */
    protected void decorateFromDTInfo(DTTagConverter dtTagConverter,
            String tagDecorateInfoID)
    {
        Element srcElement = dtTagConverter.getHostElement();
        DTManager dtManager = DTManager.getInstance();
        IDTInfo dtInfo = dtManager.getDTInfo(srcElement);
        if (dtInfo != null)
        {
            TagDecorateInfo tdInfo = dtInfo
                    .getTagDecorateInfo(tagDecorateInfoID);
            if (tdInfo != null)
            {
                dtTagConverter.setMultiLevel(tdInfo.isMultiLevel());
                dtTagConverter.setNeedBorderDecorator(tdInfo
                        .isNeedBorderDecorator());
                dtTagConverter.setNeedTableDecorator(tdInfo
                        .isNeedTableDecorator());
                if (tdInfo.isNonVisual())
                {
                    setNonVisual(dtTagConverter, dtInfo, tdInfo
                            .getNonVisualImagePath());
                }
                if (tdInfo.isResolveChildText())
                {
                    resolveChildText(dtTagConverter.getResultElement(), dtInfo);
                }
                if (tdInfo.isSetNonVisualChildElements())
                {
                    setNonVisualChildElements(dtTagConverter, srcElement);
                }
                dtTagConverter.setWidget(tdInfo.isWidget());
                dtTagConverter.setMinHeight(tdInfo.getMinHeight());
                dtTagConverter.setMinWidth(tdInfo.getMinWidth());
                ResolveAttributeValue resAttrValue = tdInfo
                        .getResolveAttributeValue();
                if (resAttrValue != null)
                {
                    String attributeName = resAttrValue.getAttributeName();
                    if (attributeName != null && attributeName.length() > 0)
                    {
                        resolveAttributeValue(dtTagConverter.getHostElement(),
                                dtTagConverter.getResultElement(),
                                attributeName, dtInfo, tagDecorateInfoID);
                    }
                }
            }
        }
    }

    /**
     * Creates a visual representation result Element for an unknown tag.
     *
     * @param dtTagConverter
     *            DTTagConverter instance.
     */
    protected void createUnknownTagRepresentation(DTTagConverter dtTagConverter)
    {
        Element element = dtTagConverter.createElement("span"); //$NON-NLS-1$
        element.setAttribute("style", "color:red;font-weight:bold;"); //$NON-NLS-1$ //$NON-NLS-2$
        Text text = dtTagConverter
                .createText("<" + dtTagConverter.getHostElement().getTagName() + "/>"); //$NON-NLS-1$ //$NON-NLS-2$
        element.appendChild(text);
        dtTagConverter.setResultElement(element);
        dtTagConverter.setWidget(true);
    }

    /**
     * Adds child Elements of the specified source Element to the specified
     * DTTagConverter instance's collection of non-visual children.
     *
     * @param dtTagConverter
     *            DTTagConverter instance.
     * @param srcElement
     *            Source Element for which child Elements are to be added.
     */
    protected void setNonVisualChildElements(DTTagConverter dtTagConverter,
            Element srcElement)
    {
        NodeList childNodes = srcElement.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++)
        {
            Node curNode = childNodes.item(i);
            if (curNode.getNodeType() == Node.ELEMENT_NODE)
            {
                dtTagConverter.addNonVisualChildElement((Element) curNode);
            }
        }
    }

    /**
     * Performs simple EL resolution for the child Text Node of the specified
     * source Element instance.
     *
     * @param srcElement
     *            Source Element for which child Text Node EL resolution is to
     *            be performed.
     * @param dtInfo
     *            IDTInfo instance.
     */
    protected void resolveChildText(Element srcElement, IDTInfo dtInfo)
    {
        if (srcElement != null)
        {
            NodeList childNodes = srcElement.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++)
            {
                Node childNode = childNodes.item(i);
                if (childNode.getNodeType() == Node.TEXT_NODE)
                {
                    Text textNode = (Text) childNode;
                    String textNodeValue = textNode.getNodeValue();
                    try
                    {
                        String newTextNodeValue;
                        if (textNodeValue.contains(MD_PLUGIN_LOCATION))
                        {
                            newTextNodeValue = resolveMDPluginLocation(
                                    textNodeValue, dtInfo);
                        } else
                        {
                            newTextNodeValue = (String) PageExpressionContext
                                    .getCurrent().evaluateExpression(
                                            textNodeValue, String.class, null);
                        }
                        if (newTextNodeValue != null
                                && !textNodeValue.equals(newTextNodeValue))
                        {
                            textNode.setNodeValue(newTextNodeValue);
                        }
                    } catch (Exception ex)
                    {
                        // ignore - could not resolve, do not change existing
                        // value
                    }
                }
            }
        }
    }

    /**
     * Performs simple EL resolution for the value of the specified attribute of
     * the specified Element.
     *
     * @param srcElement
     *
     * @param targetElement
     *            Source Element instance.
     * @param attributeName
     *            Name of attribute for which the value should be resolved.
     * @param dtInfo
     *            IDTInfo instance.
     * @param tagDecorateInfoID
     */
    protected void resolveAttributeValue(Element srcElement,
            Element targetElement, String attributeName, IDTInfo dtInfo,
            String tagDecorateInfoID)
    {
        if (targetElement != null)
        {
            String oldAttributeValue = null;
            String targetAttributeName = attributeName;
            // determine if attributeName is XPath and re-target as appropriate
            if (attributeName.contains("/")) { //$NON-NLS-1$
                int lastSlashPos = attributeName.lastIndexOf("/"); //$NON-NLS-1$
                String xPathExpression = attributeName.substring(0,
                        lastSlashPos);
                XPath xPath = XPathFactory.newInstance().newXPath();
                try
                {
                    Object resultObject = xPath.evaluate(xPathExpression,
                            targetElement, XPathConstants.NODE);
                    if (resultObject instanceof Element)
                    {
                        targetElement = (Element) resultObject;
                        targetAttributeName = attributeName
                                .substring(lastSlashPos + 1);
                    }
                    else if (resultObject instanceof Text)
                    {
                        Node parentNode = ((Text)resultObject).getParentNode();
                        if (parentNode instanceof Element)
                        {
                            parentNode.normalize();
                            targetAttributeName = IAttributeValueResolver.TEXT_NODE_KEY;
                            oldAttributeValue = ((Text)resultObject).getNodeValue();
                        }
                    }
                }
                catch (XPathExpressionException xee)
                {
                    // could not evaluate - leave targetElement and
                    // targetAttributeName unchanged
                }
            }

           
            if (!IAttributeValueResolver.TEXT_NODE_KEY.equals(targetAttributeName))
            {
                oldAttributeValue = targetElement.getAttribute(targetAttributeName);
            }

            if (oldAttributeValue != null && oldAttributeValue.length() > 0)
            {
                String newAttributeValue;
                if (oldAttributeValue.contains(MD_PLUGIN_LOCATION))
                {
                    newAttributeValue = resolveMDPluginLocation(
                            oldAttributeValue, dtInfo);
                }
                else
                {
                    newAttributeValue = resolveAttributeValue(srcElement,
                            targetElement, targetAttributeName,
                            oldAttributeValue, tagDecorateInfoID);
                }
                if (newAttributeValue != null
                        && !oldAttributeValue.equals(newAttributeValue))
                {
                    if (IAttributeValueResolver.TEXT_NODE_KEY
                            .equals(targetAttributeName))
                    {
                        for (int i = targetElement.getChildNodes().getLength()-1; i >= 0; i--)
                        {
                            Node childNode = targetElement.getChildNodes().item(i);
                            if (childNode.getNodeType() == Node.TEXT_NODE)
                            {
                                targetElement.removeChild(childNode);
                            }
                        }
                        targetElement.appendChild(targetElement.getOwnerDocument().createTextNode(newAttributeValue));
                    }
                    else
                    {
                        targetElement.setAttribute(targetAttributeName,
                                newAttributeValue);
                    }
                }
            }
        }
    }

    private String resolveAttributeValue(final Element originalElement,
            final Element convertedElement,
            final String convertedAttributeName, final String oldAttributeValue,
            final String tagDecorateInfoID)
    {
        String newValue = null;
        boolean valueResolved = false;
        final String[] result = new String[1];

        for (final IAttributeValueResolver resolver : AttributeValueResolverRegistryReader
                .getInstance().getExtensions())
        {
            SafeRunner.run(new ISafeRunnable()
            {
                public void handleException(Throwable exception)
                {
                    PDPlugin
                            .log(
                                    "While resolving attribute in converter decorator", exception); //$NON-NLS-1$
                }

                public void run() throws Exception
                {
                    if (resolver.canResolve(originalElement,
                            convertedElement, convertedAttributeName, oldAttributeValue))
                    {
                        result[0] = resolver.resolveAttribute(
                                originalElement, convertedElement,
                                convertedAttributeName, oldAttributeValue);
                    }
                }
            });
            if (result[0] != null)
            {
                newValue = result[0];
                valueResolved = true;
                break;
            }
        }

        if (!valueResolved &&
                // maintain backward compatibility: only do this default
                // behaviour for the preview
                tagDecorateInfoID.equals(DECORATE_INFO_ID_PREVIEW))
        {
            // fall- through to default case.
            try
            {
               
                PageExpressionContext current = PageExpressionContext.getCurrent();
                if (current != null)
                {
                    return (String) current
                            .evaluateExpression(oldAttributeValue, String.class,
                                    null);
                }
            } catch (ELException e)
            {
                // ignore. we will just return null since couldn't resolve
            }
        }
        return newValue;
    }

    /**
     * Resolves any instance of MD_PLUGIN_LOCATION in input String.
     *
     * @param input
     *            Input String.
     * @param dtInfo
     *            IDTInfo instance.
     * @return Input String with any instance of MD_PLUGIN_LOCATION resolved.
     */
    protected String resolveMDPluginLocation(String input, IDTInfo dtInfo)
    {
        String output = input;
        if (input != null && input.contains(MD_PLUGIN_LOCATION))
        {
            int tokenStart = input.indexOf(MD_PLUGIN_LOCATION);
            int tokenEnd = tokenStart + MD_PLUGIN_LOCATION.length();
            String prefix = input.substring(0, tokenStart);
            String suffix = input.substring(tokenEnd);
            Trait trait = dtInfo.getTrait();
            IMetaDataSourceModelProvider mdSourceModelProvider = trait
                    .getSourceModelProvider();
            IResourceURLProvider resourceURLProvider = (IResourceURLProvider) mdSourceModelProvider
                    .getAdapter(IResourceURLProvider.class);
            URL url = resourceURLProvider.getResourceURL("/META-INF/"); //$NON-NLS-1$
            String resolvedToken = url.toExternalForm();
            resolvedToken = resolvedToken.substring(0,
                    resolvedToken.length() - 10);
            output = prefix + resolvedToken + suffix;
        }
        return output;
    }

    /**
     * Sets DTTagConverter instance as non-visual as HTML and sets the
     * ImageDescriptor instance that DTTagConverter will use to return an Image
     * for rendering.
     *
     * @param dtTagConverter
     *            DTTagConverter instance.
     * @param dtInfo
     *            IDTInfo instance.
     * @param imagePath
     *            Image path, relative to declaring plug-in.
     */
    protected void setNonVisual(DTTagConverter dtTagConverter, IDTInfo dtInfo,
            String imagePath)
    {
        dtTagConverter.setVisualByHTML(false);
        if (imagePath != null && imagePath.length() > 0)
        {
            Trait trait = dtInfo.getTrait();
            IImageDescriptorProvider imgDescProvider = (IImageDescriptorProvider) trait
                    .getSourceModelProvider().getAdapter(
                            IImageDescriptorProvider.class);
            if (imgDescProvider != null)
            {
                ImageDescriptor imageDescriptor = imgDescProvider
                        .getImageDescriptor(imagePath);
                dtTagConverter.setVisualImageDescriptor(imageDescriptor);
            }
        }
    }

}
TOP

Related Classes of org.eclipse.jst.pagedesigner.dtmanager.converter.internal.DTTagConverterDecorator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.