Package org.eclipse.jst.jsf.core.internal.region

Source Code of org.eclipse.jst.jsf.core.internal.region.Region2ElementAdapter$RegionProcessorStrategy

/*******************************************************************************
* 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.core.internal.region;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jst.jsf.common.dom.ElementDOMAdapter;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.ITaglibContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.IStructuredDocumentContextResolverFactory2;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
* Adapt a region object for DOM element information. Does not implement entire
* DOM interface. Object is lazily initialized and not thread-safe.
*
* @author cbateman
*
*/
public class Region2ElementAdapter extends ElementDOMAdapter
{
    private final RegionProcessorStrategy _regionParser;

    /**
     * Create a new adapter for this region. If the region does not contain
     * enough information to construct a meaningful adapter, it will throw
     * NoElementException. The adapter is lazily initialized and won't process
     * the region until the first call to a get method is made.
     *
     * @param region
     * @throws NoElementException
     */
    public Region2ElementAdapter(final ITextRegion region)
            throws NoElementException
    {
        _regionParser = new RegionProcessorStrategy(region);
    }

    @Override
    public Map<String, Region2AttrAdapter> getAttributes()
    {
        return _regionParser.getAttributes();
    }

    @Override
    public String getNamespace()
    {
        return _regionParser.getNamespace();
    }

    @Override
    public String getLocalName()
    {
        return _regionParser.getLocalName();
    }

    @Override
    public String getNodeName()
    {
        return _regionParser.getNodeName();
    }

    @Override
    public String getPrefix()
    {
        return _regionParser.getPrefix();
    }

    /**
     * @return the structured document context
     */
    public IStructuredDocumentContext getDocumentContext()
    {
        return _regionParser._context;
    }

    /**
     * @return an ITextRegion containing absolute offset information for this element
     */
    public ITextRegionCollection getTextRegion()
    {
        return _regionParser._region;
    }

    /**
     * @return the element
     */
    public Element getElement()
    {
        return (Element) _regionParser._node;
    }

    private class RegionProcessorStrategy
    {
        private final ITextRegionCollection _region;

        private Map<String, Region2AttrAdapter> _attributes;
        private Node                        _node;
        private IStructuredDocumentContext  _context;

        RegionProcessorStrategy(final ITextRegion region) throws NoElementException
        {
            if (!(region instanceof ITextRegionCollection)
                    || ((ITextRegionCollection) region).getFirstRegion()
                            .getType() != DOMRegionContext.XML_TAG_OPEN)
            {
                throw new NoElementException(
                        "Region is not a collection with an open tag"); //$NON-NLS-1$
            }

            _region = (ITextRegionCollection) region;

            _context =
                       IStructuredDocumentContextFactory.INSTANCE.getContext(
                               ((IStructuredDocumentRegion) _region)
                                       .getParentDocument(), _region
                                       .getStartOffset());

            if (_context == null)
            {
                throw new NoElementException(
                        "Couldn't acquire structured document context"); //$NON-NLS-1$
            }

            final IDOMContextResolver resolver =
                                                 IStructuredDocumentContextResolverFactory.INSTANCE
                                                         .getDOMContextResolver(_context);

            if (resolver == null)
            {
                throw new NoElementException("Couldn't acquire dom resolver"); //$NON-NLS-1$
            }

            _node = resolver.getNode();

            if (_node == null)
            {
                throw new NoElementException("Couldn't get Node from region"); //$NON-NLS-1$
            }
        }

        public String getLocalName()
        {
            return _node.getLocalName();
        }

        public String getNodeName()
        {
            return _node.getNodeName();
        }

        public String getPrefix()
        {
            return _node.getPrefix();
        }

        public String getNamespace()
        {
            final ITaglibContextResolver tagLibResolver =
                              IStructuredDocumentContextResolverFactory2.INSTANCE
                                      .getTaglibContextResolverFromDelegates(_context);

            if (tagLibResolver != null)
            {
                return tagLibResolver.getTagURIForNodeName(_node);
            }

            return null;
        }

        public Map<String, Region2AttrAdapter>  getAttributes()
        {
            mapAttributesOnlyOnce();
            return Collections.unmodifiableMap(_attributes);
        }

        private void mapAttributesOnlyOnce()
        {
            // only once
            if (_attributes != null)
                return;

            _attributes = Collections.EMPTY_MAP;

            final NamedNodeMap attributes = _node.getAttributes();

            if (attributes != null)
            {
                final int numAttrs = attributes.getLength();
                _attributes = new HashMap<String, Region2AttrAdapter>(
                        (int) (numAttrs / 0.75f) + 1, 0.75f);
                for (int i = 0; i < numAttrs; i++)
                {
                    final Node nodeAttr = attributes.item(i);
                    Region2AttrAdapter attr = new Region2AttrAdapter(
                            Region2ElementAdapter.this, nodeAttr);
                    _attributes.put(attr.getLocalName(), attr);
                }
            }
        }
    }
   
    /**
     * Indicates that construction of this adapter failed because an IRegion
     * didn't have sufficient information (or didn't represent an element at
     * all)
     *
     * @author cbateman
     *
     */
    public static class NoElementException extends Exception
    {
        /**
         * serializable id
         */
        private static final long serialVersionUID = -4479154049727036580L;

        private NoElementException(final String reason)
        {
            super(reason);
        }
    }
}
TOP

Related Classes of org.eclipse.jst.jsf.core.internal.region.Region2ElementAdapter$RegionProcessorStrategy

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.