Author: snjeza
Date: 2008-04-15 17:31:05 -0400 (Tue, 15 Apr 2008)
New Revision: 7542
Added:
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorations.java
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorationsManager.java
Modified:
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/ClasspathCorePlugin.java
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainer.java
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainerInitializer.java
Log:
JBIDE-1401 allow users to edit our classpathcontainers for src/javadoc etc.
Modified:
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/ClasspathCorePlugin.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/ClasspathCorePlugin.java 2008-04-15
21:17:42 UTC (rev 7541)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/ClasspathCorePlugin.java 2008-04-15
21:31:05 UTC (rev 7542)
@@ -1,6 +1,9 @@
package org.jboss.ide.eclipse.as.classpath.core;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
/**
@@ -47,4 +50,9 @@
return plugin;
}
+ public static void log(String msg,Throwable e) {
+ ILog log = ClasspathCorePlugin.getDefault().getLog();
+ IStatus status = new Status(Status.ERROR,ClasspathCorePlugin.PLUGIN_ID,msg,e);
+ log.log(status);
+ }
}
Modified:
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainer.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainer.java 2008-04-15
21:17:42 UTC (rev 7541)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainer.java 2008-04-15
21:31:05 UTC (rev 7542)
@@ -27,15 +27,20 @@
import java.net.URL;
import java.util.ArrayList;
+import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.jboss.ide.eclipse.as.classpath.core.ClasspathCorePlugin;
+import org.jboss.ide.eclipse.as.classpath.core.xpl.ClasspathDecorations;
+import org.jboss.ide.eclipse.as.classpath.core.xpl.ClasspathDecorationsManager;
/**
*
@@ -53,6 +58,12 @@
protected String description;
protected String libFolder;
+ private static ClasspathDecorationsManager decorations;
+ static {
+
+ decorations = new ClasspathDecorationsManager();
+ }
+
public AbstractClasspathContainer(IPath path, String description,
String libFolder) {
this.path = path;
@@ -109,15 +120,28 @@
IPath sourceAttachementPath = null;
IPath sourceAttachementRootPath = null;
- if (jarSrcFile.exists()) {
- sourceAttachementPath = new Path(jarSrcFile.toString());
- sourceAttachementRootPath = new Path("/");//$NON-NLS-1$
- }
-
- IClasspathEntry entry = JavaCore.newLibraryEntry(entryPath,
- sourceAttachementPath, sourceAttachementRootPath, true);
- entries.add(entry);
+ final ClasspathDecorations dec
+ = decorations.getDecorations( getDecorationManagerKey(getPath().toString()),
entryPath.toString() );
+
+
+ IClasspathAttribute[] attrs = {};
+ if( dec != null )
+ {
+ sourceAttachementPath = dec.getSourceAttachmentPath();
+ sourceAttachementRootPath = dec.getSourceAttachmentRootPath();
+ attrs = dec.getExtraAttributes();
+ } else if (jarSrcFile.exists()) {
+ sourceAttachementPath = new Path(jarSrcFile.toString());
+ sourceAttachementRootPath = new Path("/");//$NON-NLS-1$
}
+
+ IAccessRule[] access = {};
+ IClasspathEntry entry = JavaCore.newLibraryEntry( entryPath, sourceAttachementPath,
sourceAttachementRootPath, access, attrs,
+ false );
+ // IClasspathEntry entry = JavaCore.newLibraryEntry(entryPath,
+ // sourceAttachementPath, sourceAttachementRootPath, true);
+ entries.add(entry);
+ }
}
return (IClasspathEntry[]) entries.toArray(new IClasspathEntry[entries
@@ -140,4 +164,18 @@
}
return null;
}
+
+ public static String getDecorationManagerKey( String container){
+ return container;
+ }
+
+ static ClasspathDecorationsManager getDecorationsManager()
+ {
+ return decorations;
+ }
+
+ public void refresh() {
+ entries = computeEntries();
+ }
+
}
Modified:
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainerInitializer.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainerInitializer.java 2008-04-15
21:17:42 UTC (rev 7541)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/jee/AbstractClasspathContainerInitializer.java 2008-04-15
21:31:05 UTC (rev 7542)
@@ -24,50 +24,105 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.ClasspathContainerInitializer;
+import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
+import org.jboss.ide.eclipse.as.classpath.core.xpl.ClasspathDecorations;
+import org.jboss.ide.eclipse.as.classpath.core.xpl.ClasspathDecorationsManager;
/**
*
* @author Rob Stryker <rob.stryker(a)redhat.com>
- *
+ *
*/
-public abstract class AbstractClasspathContainerInitializer extends
ClasspathContainerInitializer {
- public AbstractClasspathContainerInitializer() {
- }
+public abstract class AbstractClasspathContainerInitializer extends
+ ClasspathContainerInitializer {
+
+ public AbstractClasspathContainerInitializer() {
+ }
- /**
- * Description of the Method
- *
- * @param containerPath Description of the Parameter
- * @param project Description of the Parameter
- * @exception CoreException Description of the Exception
- */
- public void initialize(IPath containerPath, IJavaProject project) throws CoreException
{
- int size = containerPath.segmentCount();
- if (size > 0) {
- if (containerPath.segment(0).equals(this.getClasspathContainerID())) {
- AbstractClasspathContainer container =
this.createClasspathContainer(containerPath);
- JavaCore.setClasspathContainer(containerPath, new IJavaProject[]
- {project}, new IClasspathContainer[]
- {container}, null);
- }
- }
- }
+ /**
+ * Description of the Method
+ *
+ * @param containerPath
+ * Description of the Parameter
+ * @param project
+ * Description of the Parameter
+ * @exception CoreException
+ * Description of the Exception
+ */
+ public void initialize(IPath containerPath, IJavaProject project)
+ throws CoreException {
+ int size = containerPath.segmentCount();
+ if (size > 0) {
+ if (containerPath.segment(0).equals(this.getClasspathContainerID())) {
+ AbstractClasspathContainer container = this
+ .createClasspathContainer(containerPath);
+ JavaCore.setClasspathContainer(containerPath,
+ new IJavaProject[] { project },
+ new IClasspathContainer[] { container }, null);
+ }
+ }
+ }
- /**
- * Description of the Method
- *
- * @param path Description of the Parameter
- * @return Description of the Return Value
- */
- protected abstract AbstractClasspathContainer createClasspathContainer(IPath path);
+ /**
+ * Description of the Method
+ *
+ * @param path
+ * Description of the Parameter
+ * @return Description of the Return Value
+ */
+ protected abstract AbstractClasspathContainer createClasspathContainer(
+ IPath path);
- /**
- * Gets the classpathContainerID attribute of the
AbstractClasspathContainerInitializer object
- *
- * @return The classpathContainerID value
- */
- protected abstract String getClasspathContainerID();
+ /**
+ * Gets the classpathContainerID attribute of the
+ * AbstractClasspathContainerInitializer object
+ *
+ * @return The classpathContainerID value
+ */
+ protected abstract String getClasspathContainerID();
+
+ public boolean canUpdateClasspathContainer(IPath containerPath,
+ IJavaProject project) {
+ return true;
+ }
+
+ public void requestClasspathContainerUpdate(final IPath containerPath,
+ final IJavaProject project, final IClasspathContainer sg)
+
+ throws CoreException
+
+ {
+ String key = AbstractClasspathContainer
+ .getDecorationManagerKey(containerPath.toString());
+
+ IClasspathEntry[] entries = sg.getClasspathEntries();
+ ClasspathDecorationsManager decorations = AbstractClasspathContainer
+ .getDecorationsManager();
+ decorations.clearAllDecorations(key);
+
+ for (int i = 0; i < entries.length; i++) {
+ final IClasspathEntry entry = entries[i];
+
+ final IPath srcpath = entry.getSourceAttachmentPath();
+ final IPath srcrootpath = entry.getSourceAttachmentRootPath();
+ final IClasspathAttribute[] attrs = entry.getExtraAttributes();
+ final String eid = entry.getPath().toString();
+ final ClasspathDecorations dec = new ClasspathDecorations();
+
+ dec.setSourceAttachmentPath(srcpath);
+ dec.setSourceAttachmentRootPath(srcrootpath);
+ dec.setExtraAttributes(attrs);
+
+ decorations.setDecorations(key, eid, dec);
+ }
+ decorations.save();
+ final IClasspathContainer container = JavaCore.getClasspathContainer(
+ containerPath, project);
+ ((AbstractClasspathContainer) container).refresh();
+ }
+
}
Added:
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorations.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorations.java
(rev 0)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorations.java 2008-04-15
21:31:05 UTC (rev 7542)
@@ -0,0 +1,65 @@
+/******************************************************************************
+ * Copyright (c) 2005 BEA Systems, Inc.
+ * 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:
+ * Konstantin Komissarchik - initial API and implementation
+ ******************************************************************************/
+
+package org.jboss.ide.eclipse.as.classpath.core.xpl;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.JavaCore;
+
+/**
+ * @author <a href="mailto:kosta@bea.com">Konstantin
Komissarchik</a>
+ */
+
+public final class ClasspathDecorations {
+ private IPath sourceAttachmentPath;
+ private IPath sourceAttachmentRootPath;
+ private ArrayList extraAttributes = new ArrayList();
+
+ public IPath getSourceAttachmentPath() {
+ return this.sourceAttachmentPath;
+ }
+
+ public void setSourceAttachmentPath(final IPath sourceAttachmentPath) {
+ this.sourceAttachmentPath = sourceAttachmentPath;
+ }
+
+ public IPath getSourceAttachmentRootPath() {
+ return this.sourceAttachmentRootPath;
+ }
+
+ public void setSourceAttachmentRootPath(final IPath sourceAttachmentRootPath) {
+ this.sourceAttachmentRootPath = sourceAttachmentRootPath;
+ }
+
+ public IClasspathAttribute[] getExtraAttributes() {
+ final IClasspathAttribute[] array = new IClasspathAttribute[this.extraAttributes
+ .size()];
+
+ return (IClasspathAttribute[]) this.extraAttributes.toArray(array);
+ }
+
+ public void setExtraAttributes(final IClasspathAttribute[] attrs) {
+ for (int i = 0; i < attrs.length; i++) {
+ this.extraAttributes.add(attrs[i]);
+ }
+ }
+
+ public void addExtraAttribute(final String name, final String value) {
+ final IClasspathAttribute attr = JavaCore.newClasspathAttribute(name,
+ value);
+
+ this.extraAttributes.add(attr);
+ }
+
+}
Added:
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorationsManager.java
===================================================================
---
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorationsManager.java
(rev 0)
+++
trunk/as/plugins/org.jboss.ide.eclipse.as.classpath.core/src/org/jboss/ide/eclipse/as/classpath/core/xpl/ClasspathDecorationsManager.java 2008-04-15
21:31:05 UTC (rev 7542)
@@ -0,0 +1,316 @@
+package org.jboss.ide.eclipse.as.classpath.core.xpl;
+
+/******************************************************************************
+ * Copyright (c) 2005 BEA Systems, Inc.
+ * 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:
+ * Konstantin Komissarchik - initial API and implementation
+ ******************************************************************************/
+
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.jboss.ide.eclipse.as.classpath.core.ClasspathCorePlugin;
+import org.osgi.service.prefs.BackingStoreException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * @author <a href="mailto:kosta@bea.com">Konstantin
Komissarchik</a>
+ */
+
+public final class ClasspathDecorationsManager {
+ private static final String CLASSPATH_PREFERENCES = "classpathPreferences";
+ private static final String SEPARATOR = System
+ .getProperty("line.separator");
+ private final HashMap decorations;
+
+ public ClasspathDecorationsManager() {
+ this.decorations = read();
+ }
+
+ private IEclipsePreferences getEclipsePreferences() {
+ IEclipsePreferences node = (IEclipsePreferences) Platform
+ .getPreferencesService().getRootNode()
+ .node(InstanceScope.SCOPE).node(ClasspathCorePlugin.PLUGIN_ID);
+ return node;
+ }
+
+ private String getPreferences() {
+ return getEclipsePreferences().get(CLASSPATH_PREFERENCES, null);
+ }
+
+ public ClasspathDecorations getDecorations(final String key,
+ final String entry) {
+ final HashMap submap = (HashMap) this.decorations.get(key);
+
+ if (submap == null) {
+ return null;
+ }
+
+ return (ClasspathDecorations) submap.get(entry);
+ }
+
+ public void setDecorations(final String key, final String entry,
+ final ClasspathDecorations dec) {
+ HashMap submap = (HashMap) this.decorations.get(key);
+
+ if (submap == null) {
+ submap = new HashMap();
+ this.decorations.put(key, submap);
+ }
+
+ submap.put(entry, dec);
+ }
+
+ public void clearAllDecorations(final String key) {
+ this.decorations.remove(key);
+ }
+
+ public void save() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<classpath>"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+ for (Iterator itr1 = decorations.entrySet().iterator(); itr1.hasNext();) {
+ final Map.Entry entry1 = (Map.Entry) itr1.next();
+ final Map submap = (Map) entry1.getValue();
+
+ buffer.append(" <container id=\""); //$NON-NLS-1$
+ buffer.append((String) entry1.getKey());
+ buffer.append("\">"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+
+ for (Iterator itr2 = submap.entrySet().iterator(); itr2.hasNext();) {
+ final Map.Entry entry2 = (Map.Entry) itr2.next();
+
+ final ClasspathDecorations dec = (ClasspathDecorations) entry2
+ .getValue();
+
+ buffer.append(" <entry id=\""); //$NON-NLS-1$
+ buffer.append((String) entry2.getKey());
+ buffer.append("\">"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+
+ String src = "";
+ if (dec.getSourceAttachmentPath() != null) {
+ src = dec.getSourceAttachmentPath().toString();
+ }
+ buffer.append(" <source-attachment-path>"); //$NON-NLS-1$
+ buffer.append(src);
+ buffer.append("</source-attachment-path>"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+
+ if (dec.getSourceAttachmentRootPath() != null) {
+ buffer.append(" <source-attachment-root-path>"); //$NON-NLS-1$
+ buffer.append(dec.getSourceAttachmentRootPath().toString());
+ buffer.append("</source-attachment-root-path>"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+ }
+
+ final IClasspathAttribute[] attrs = dec.getExtraAttributes();
+
+ for (int i = 0; i < attrs.length; i++) {
+ final IClasspathAttribute attr = attrs[i];
+
+ buffer.append(" <attribute name=\""); //$NON-NLS-1$
+ buffer.append(attr.getName());
+ buffer.append("\">"); //$NON-NLS-1$
+ buffer.append(attr.getValue());
+ buffer.append("</attribute>"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+ }
+
+ buffer.append(" </entry>"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+ }
+
+ buffer.append(" </container>"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+ }
+
+ buffer.append("</classpath>"); //$NON-NLS-1$
+ buffer.append(SEPARATOR);
+ IEclipsePreferences ep = getEclipsePreferences();
+ ep.put(CLASSPATH_PREFERENCES, buffer.toString());
+ try {
+ ep.flush();
+ } catch (BackingStoreException e) {
+ String msg = "Encountered an unexpected exception.";
+ ClasspathCorePlugin.log(msg, e);
+ }
+ }
+
+ private HashMap read() {
+ final HashMap map = new HashMap();
+ String prefs = getPreferences();
+ if (prefs == null || prefs.length() <= 0)
+ return map;
+
+ Element root = null;
+ try {
+ final DocumentBuilderFactory factory = DocumentBuilderFactory
+ .newInstance();
+
+ final DocumentBuilder docbuilder = factory.newDocumentBuilder();
+
+ StringReader reader = new StringReader(prefs);
+ InputSource source = new InputSource(reader);
+ root = docbuilder.parse(source).getDocumentElement();
+ } catch (Exception e) {
+ String msg = "Encountered an unexpected exception.";
+ ClasspathCorePlugin.log(msg, e);
+ return map;
+ }
+
+ for (Iterator itr1 = elements(root, "container"); itr1.hasNext();)
//$NON-NLS-1$
+ {
+ final Element e1 = (Element) itr1.next();
+ final String cid = e1.getAttribute("id"); //$NON-NLS-1$
+
+ final HashMap submap = new HashMap();
+ map.put(cid, submap);
+
+ for (Iterator itr2 = elements(e1, "entry"); itr2.hasNext();) //$NON-NLS-1$
+ {
+ final Element e2 = (Element) itr2.next();
+ final String eid = e2.getAttribute("id"); //$NON-NLS-1$
+ final ClasspathDecorations dec = new ClasspathDecorations();
+
+ submap.put(eid, dec);
+
+ for (Iterator itr3 = elements(e2); itr3.hasNext();) {
+ final Element e3 = (Element) itr3.next();
+ final String n = e3.getNodeName();
+ String text = text(e3);
+ if (text != null) {
+ if (n.equals("source-attachment-path")) //$NON-NLS-1$
+ {
+ dec.setSourceAttachmentPath(new Path(text(e3)));
+ } else if (n.equals("source-attachment-root-path")) //$NON-NLS-1$
+ {
+ dec.setSourceAttachmentRootPath(new Path(text(e3)));
+ }
+ }
+ if (n.equals("attribute")) //$NON-NLS-1$
+ {
+ final String name = e3.getAttribute("name"); //$NON-NLS-1$
+ dec.addExtraAttribute(name, text(e3));
+ }
+
+ }
+ }
+ }
+
+ return map;
+ }
+
+ private static String text(final Element el) {
+ final NodeList nodes = el.getChildNodes();
+
+ String str = null;
+ StringBuffer buf = null;
+
+ for (int i = 0, n = nodes.getLength(); i < n; i++) {
+ final Node node = nodes.item(i);
+
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ final String val = node.getNodeValue();
+
+ if (buf != null) {
+ buf.append(val);
+ } else if (str != null) {
+ buf = new StringBuffer();
+ buf.append(str);
+ buf.append(val);
+
+ str = null;
+ } else {
+ str = val;
+ }
+ }
+ }
+
+ if (buf != null) {
+ return buf.toString();
+ }
+ return str;
+ }
+
+ private static Iterator elements(final Element el, final String name) {
+ return new ElementsIterator(el, name);
+ }
+
+ private static Iterator elements(final Element el) {
+ return new ElementsIterator(el, null);
+ }
+
+ private static final class ElementsIterator implements Iterator {
+ private final NodeList nodes;
+ private final int length;
+ private final String name;
+ private int position;
+ private Element element;
+
+ public ElementsIterator(final Element parent, final String name) {
+ this.nodes = parent.getChildNodes();
+ this.length = nodes.getLength();
+ this.position = -1;
+ this.name = name;
+
+ advance();
+ }
+
+ private void advance() {
+ this.element = null;
+ this.position++;
+
+ for (; this.position < this.length && this.element == null;
this.position++) {
+ final Node node = this.nodes.item(this.position);
+
+ if (node.getNodeType() == Node.ELEMENT_NODE
+ && (this.name == null || node.getNodeName().equals(
+ this.name))) {
+ this.element = (Element) node;
+ }
+ }
+ }
+
+ public boolean hasNext() {
+ return (this.element != null);
+ }
+
+ public Object next() {
+ final Element el = this.element;
+
+ if (el == null) {
+ throw new NoSuchElementException();
+ }
+
+ advance();
+
+ return el;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+}