Package org.eclipse.jst.jsf.designtime.internal.view

Source Code of org.eclipse.jst.jsf.designtime.internal.view.XMLViewObjectMappingService$ElementData

/*******************************************************************************
* Copyright (c) 2001, 2008 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.jsf.designtime.internal.view;

import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.jsf.common.dom.TagIdentifier;
import org.eclipse.jst.jsf.common.runtime.internal.model.ViewObject;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.region.Region2ElementAdapter;
import org.eclipse.jst.jsf.core.internal.region.Region2ElementAdapter.NoElementException;
import org.eclipse.jst.jsf.core.internal.tld.TagIdentifierFactory;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.w3c.dom.Element;

/**
* @author cbateman
*
*/
public final class XMLViewObjectMappingService implements Serializable
{
    /**
     *
     */
    private static final long serialVersionUID = -5371998199186683997L;
    private final Map<ElementData, ViewObject> _elementToViewObjMap;
    private final Map<ViewObject, ElementData> _viewObjToElementMap;

    /**
     *
     */
    public XMLViewObjectMappingService()
    {
        _elementToViewObjMap = new HashMap<ElementData, ViewObject>();
        _viewObjToElementMap = new HashMap<ViewObject, ElementData>();
    }

    /**
     * @param elementData
     * @param viewObject
     */
    public void createMapping(final ElementData elementData,
            final ViewObject viewObject)
    {
        if (elementData == null)
        {
            throw new IllegalArgumentException("elementData cannot be null"); //$NON-NLS-1$
        }
        else if (viewObject == null)
        {
            throw new IllegalArgumentException("viewObject cannot be null"); //$NON-NLS-1$
        }

        synchronized(this)
        {
            _elementToViewObjMap.put(elementData, viewObject);
            _viewObjToElementMap.put(viewObject, elementData);
        }
    }

    /**
     * Remove all mappings
     */
    public void clearMappings()
    {
        synchronized (this)
        {
            _elementToViewObjMap.clear();
            _viewObjToElementMap.clear();
        }
    }

    /**
     * @param elementData
     * @return the view object for which the mapping was removed
     */
    public ViewObject removeMapping(final ElementData elementData)
    {
        if (elementData == null)
        {
            throw new IllegalArgumentException("elementData mustn't be null"); //$NON-NLS-1$
        }

        ViewObject viewObject = null;
        synchronized(this)
        {
            viewObject = _elementToViewObjMap.remove(elementData);
            if (viewObject != null)
            {
                _viewObjToElementMap.remove(viewObject);
            }
        }
        return viewObject;
    }

    /**
     * @param viewObject
     * @return the element data for which the mapping was removed
     */
    public ElementData removeMapping(final ViewObject viewObject)
    {
        if (viewObject == null)
        {
            throw new IllegalArgumentException("elementData mustn't be null"); //$NON-NLS-1$
        }
       
        ElementData elementData = null;
        synchronized(this)
        {
            elementData = _viewObjToElementMap.remove(viewObject);
            if (elementData != null)
            {
                _elementToViewObjMap.remove(elementData);
            }
        }
        return elementData;
    }

    /**
     * @param viewObject
     * @return the element data for the view object
     */
    public synchronized ElementData findElementData(final ViewObject viewObject)
    {
        return _viewObjToElementMap.get(viewObject);
    }

    /**
     * @param viewObject
     * @return the element for the viewObject
     */
    public Element findElement(final ViewObject viewObject)
    {
        final ElementData elementData = findElementData(viewObject);

        if (elementData != null)
        {
            final IFile file = ResourcesPlugin.getWorkspace().getRoot()
                    .getFile(new Path(elementData.getDocumentPath()));

            if (file != null && file.isAccessible())
            {
                IStructuredModel model = null;
                try
                {
                    model = StructuredModelManager.getModelManager()
                            .getModelForRead(file);
                    final IStructuredDocument sDoc = model
                            .getStructuredDocument();
                    final IStructuredDocumentRegion region = sDoc
                            .getRegionAtCharacterOffset(elementData
                                    .getStartOffset());
                    final Region2ElementAdapter adapter = new Region2ElementAdapter(
                            region);
                    final TagIdentifier tagId = adapter.getTagId();
                    if (tagId.equals(elementData.getTagId()))
                    {
                        return adapter.getElement();
                    }
                }
                catch (CoreException ce)
                {
                    JSFCorePlugin.log(ce,
                            "While finding element for viewObject: " //$NON-NLS-1$
                                    + viewObject.toString() + " in " //$NON-NLS-1$
                                    + file.getFullPath());
                }
                catch (IOException e)
                {
                    JSFCorePlugin.log(e,
                            "While finding element for viewObject: " //$NON-NLS-1$
                                    + viewObject.toString() + " in " //$NON-NLS-1$
                                    + file.getFullPath());
                }
                catch (NoElementException e)
                {
                    JSFCorePlugin.log(e,
                            "While finding element for viewObject: " //$NON-NLS-1$
                                    + viewObject.toString() + " in " //$NON-NLS-1$
                                    + file.getFullPath());
                }
                finally
                {
                    if (model != null)
                    {
                        model.releaseFromRead();
                    }
                }
            }
        }
        return null;
    }

    /**
     * @param elementData
     * @return the mapped view object for elementData or null if not found.
     */
    public synchronized ViewObject findViewObject(final ElementData elementData)
    {
        return _elementToViewObjMap.get(elementData);
    }

    /**
     * @param namespace
     * @param tagName
     * @param context
     * @param attributeToPropertyMap
     * @return a new Element data for the namespace/element name in 'context'
     */
    public static ElementData createElementData(final String namespace,
            final String tagName, final IStructuredDocumentContext context,
            final Map<String, String> attributeToPropertyMap)
    {
        final IFile file = getFile(context);
        final int offset = context.getDocumentPosition();

        if (file != null && file.isAccessible() && offset > -1
                && tagName != null && namespace != null)
        {
            return new ElementData(offset, file.getFullPath().toString(),
                    TagIdentifierFactory
                            .createJSPTagWrapper(namespace, tagName),
                     attributeToPropertyMap);
        }
        return null;
    }

    private static IFile getFile(final IStructuredDocumentContext context)
    {
        final IWorkspaceContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE
                .getWorkspaceContextResolver(context);
        IResource res = resolver.getResource();
        if (res instanceof IFile)
        {
            return (IFile) res;
        }
        // fall through.
        return null;
    }

    /**
     * Describes enough information about an element instance to look it up
     * again, without storing possibly transient references to it.
     *
     * @author cbateman
     *
     */
    public final static class ElementData implements Serializable
    {
        /**
         * serializable id
         */
        private static final long       serialVersionUID = 7937312530318827977L;

        private transient TagIdentifier _tagId;
        private Map<String, String>     _attributeToPropertyMap;
        private String                  _documentPath;
        private int                     _startOffset;

        /**
         * @param startOffset
         * @param documentPath
         * @param tagId
         * @param attributeToPropertyMap constructor takes copy of map
         */
        private ElementData(final int startOffset, final String documentPath,
                final TagIdentifier tagId, Map<String, String> attributeToPropertyMap)
        {
            super();
            _startOffset = startOffset;
           
            _tagId = tagId;
            _documentPath = documentPath;
            _attributeToPropertyMap = Collections.unmodifiableMap(
                    new HashMap<String,String>(attributeToPropertyMap));
        }

        /**
         * Default constructor
         */
        protected ElementData()
        {
            // for serialization
        }

        /**
         * @return the tag identifier for this element
         */
        public final TagIdentifier getTagId()
        {
            return _tagId;
        }

        /**
         * @param forTagAttribute
         * @return the name of the view object property that forTagAttribute
         * maps to on this element or null if none.
         */
        public final String getPropertyName(final String forTagAttribute)
        {
            return _attributeToPropertyMap.get(forTagAttribute);
        }

        final int getStartOffset()
        {
            return _startOffset;
        }

        final String getDocumentPath()
        {
            return _documentPath;
        }

        private void writeObject(final java.io.ObjectOutputStream out)
                throws IOException
        {
            out.defaultWriteObject();
            out.writeObject(_tagId.getUri());
            out.writeObject(_tagId.getTagName());
        }

        private void readObject(final java.io.ObjectInputStream in)
                throws IOException, ClassNotFoundException
        {
            in.defaultReadObject();
            final String uri = (String) in.readObject();
            final String tagName = (String) in.readObject();
            _tagId = TagIdentifierFactory.createJSPTagWrapper(uri, tagName);
        }

        @Override
        public boolean equals(final Object obj)
        {
            if (this == obj)
            {
                return true;
            }
            if (obj instanceof ElementData)
            {
                final ElementData other = (ElementData) obj;
                return _startOffset == other._startOffset
                        && _documentPath.equals(other._documentPath)
                        && _tagId.equals(other._tagId);
            }
            return false;
        }

        @Override
        public int hashCode()
        {
            int hashCode = _tagId.hashCode();
            hashCode ^= _documentPath.hashCode();
            // startOffsets will generally fit in the first 10 bits, so mix
            // it up a bit.
            hashCode ^= ~(_startOffset * 104551);
            return hashCode;
        }
    }
}
TOP

Related Classes of org.eclipse.jst.jsf.designtime.internal.view.XMLViewObjectMappingService$ElementData

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.