| /******************************************************************************* |
| * Copyright (c) 2006 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: |
| * Cameron Bateman/Oracle - initial API and implementation |
| * |
| ********************************************************************************/ |
| |
| package org.eclipse.jst.jsf.context.resolver.structureddocument.internal.impl; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.jst.jsf.context.IModelContext; |
| import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver; |
| 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.IStructuredDocument; |
| import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; |
| import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection; |
| import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList; |
| |
| /*package*/ class TextRegionContextResolver implements ITextRegionContextResolver { |
| |
| private final IStructuredDocumentContext _context; |
| |
| /*package*/ TextRegionContextResolver(IStructuredDocumentContext context) |
| { |
| _context = context; |
| } |
| |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getRegionText() |
| */ |
| public String getRegionText() |
| { |
| final ITextRegionCollection parent = getParentRegion(); |
| String text = null; |
| |
| if (parent != null) |
| { |
| ITextRegion me = parent.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| text = parent.getText(me); |
| } |
| |
| return text; |
| } |
| |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getEndOffset() |
| */ |
| public int getEndOffset() { |
| final ITextRegionCollection parent = getParentRegion(); |
| int endOffset = -1; |
| if (parent != null) |
| { |
| ITextRegion me = parent.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| endOffset = parent.getEndOffset(me); |
| } |
| |
| return endOffset; |
| } |
| |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getLength() |
| */ |
| public int getLength() { |
| final ITextRegionCollection parent = getParentRegion(); |
| int length = -1; |
| if (parent != null) |
| { |
| ITextRegion me = parent.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| length = me.getLength(); |
| } |
| |
| return length; |
| |
| } |
| |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getStartOffset() |
| */ |
| public int getStartOffset() |
| { |
| final ITextRegionCollection parent = getParentRegion(); |
| int startOffset = -1; |
| if (parent != null) |
| { |
| ITextRegion me = parent.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| startOffset = parent.getStartOffset(me); |
| } |
| |
| return startOffset; |
| } |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getRegionType() |
| */ |
| public String getRegionType() |
| { |
| final ITextRegionCollection parent = getParentRegion(); |
| String regionType = null; |
| |
| if (parent != null) |
| { |
| ITextRegion me = parent.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| |
| if (me != null) |
| { |
| regionType = me.getType(); |
| } |
| } |
| |
| return regionType; |
| } |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getRegionTypePath() |
| */ |
| public String[] getRegionTypePath() { |
| final ITextRegion[] path = createPathToContext(); |
| final String[] typePath = new String[path.length]; |
| |
| for (int i = 0; i < path.length; i++) |
| { |
| typePath[i] = path[i].getType(); |
| } |
| |
| return typePath; |
| } |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getNextContext() |
| */ |
| public IStructuredDocumentContext getNextContext() |
| { |
| ITextRegionCollection parent = getParentRegion(); |
| IStructuredDocumentContext newContext = null; |
| |
| if (parent != null) |
| { |
| final ITextRegion me = parent.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| ITextRegionList regions = parent.getRegions(); |
| ITextRegion nextRegion = null; |
| for (final Iterator it = regions.iterator(); it.hasNext();) |
| { |
| if (it.next() == me |
| && it.hasNext()) |
| { |
| nextRegion = (ITextRegion) it.next(); |
| } |
| } |
| |
| if (nextRegion != null) |
| { |
| // use the first position offset in the next region |
| final int documentPosition = parent.getStartOffset(nextRegion); |
| newContext = |
| IStructuredDocumentContextFactory.INSTANCE.getContext(_context.getStructuredDocument(), documentPosition); |
| } |
| } |
| |
| return newContext; |
| } |
| |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#getPreviousContext() |
| */ |
| public IStructuredDocumentContext getPreviousContext() |
| { |
| ITextRegionCollection parent = getParentRegion(); |
| IStructuredDocumentContext newContext = null; |
| |
| if (parent != null) |
| { |
| final ITextRegion me = parent.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| ITextRegionList regions = parent.getRegions(); |
| final Iterator it = regions.iterator(); |
| ITextRegion prevRegion = null; |
| ITextRegion nextRegion = null; |
| |
| SEARCH_LOOP: while (it.hasNext()) |
| { |
| nextRegion = (ITextRegion) it.next(); |
| |
| if (nextRegion == me) |
| { |
| break SEARCH_LOOP; |
| } |
| |
| prevRegion = nextRegion; |
| } |
| |
| if (prevRegion != null) |
| { |
| // use the last position offset in the prev region |
| final int documentPosition = parent.getStartOffset(prevRegion); |
| newContext = |
| IStructuredDocumentContextFactory.INSTANCE.getContext(_context.getStructuredDocument(), documentPosition); |
| } |
| } |
| |
| return newContext; |
| } |
| |
| private ITextRegionCollection getParentRegion() |
| { |
| final ITextRegion[] path = createPathToContext(); |
| ITextRegionCollection parent = null; |
| |
| if (path.length > 0) |
| { |
| parent = (ITextRegionCollection) path[path.length-1]; |
| } |
| |
| return parent; |
| } |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#matchesRelative(java.lang.String[]) |
| */ |
| public boolean matchesRelative(String[] path) { |
| final ITextRegion[] myPath = createPathToContext(); |
| return matchPath(myPath, path); |
| } |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver#matchesAbsolute(java.lang.String[]) |
| */ |
| public boolean matchesAbsolute(String[] path) |
| { |
| final ITextRegion[] myPath = createPathToContext(); |
| // only works if myPath and path are the same length |
| return (myPath.length == path.length) |
| && matchPath(myPath, path); |
| } |
| |
| private boolean matchPath(ITextRegion[] myPath, String[] path) |
| { |
| boolean matches = false; |
| |
| // only makes sense if path is a containing subset of myPath |
| if (path.length <= myPath.length) |
| { |
| matches = true; |
| SEARCH_LOOP: |
| for (int i = 1; i <= path.length; i++) |
| { |
| if (!path[path.length-i].equals(myPath[myPath.length-i].getType())) |
| { |
| matches = false; |
| break SEARCH_LOOP; |
| } |
| } |
| } |
| |
| return matches; |
| } |
| |
| /** |
| * @see org.eclipse.jst.jsf.context.resolver.IContextResolver#canResolveContext(org.eclipse.jst.jsf.context.IModelContext) |
| */ |
| public boolean canResolveContext(IModelContext modelContext) |
| { |
| return (modelContext.getAdapter(IStructuredDocumentContext.class) != null); |
| } |
| |
| private ITextRegion[] createPathToContext() |
| { |
| final List regionPath = new ArrayList(); |
| |
| final IStructuredDocument doc = (IStructuredDocument) _context.getStructuredDocument(); |
| |
| ITextRegion container = doc.getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| |
| while(container != null |
| && container instanceof ITextRegionCollection) |
| { |
| regionPath.add(container); |
| container = ((ITextRegionCollection)container).getRegionAtCharacterOffset(_context.getDocumentPosition()); |
| } |
| |
| return (ITextRegion[]) regionPath.toArray(new ITextRegion[0]); |
| } |
| } |