1   package org.apache.maven.project.harness;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import org.apache.commons.jxpath.ri.Compiler;
26  import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
27  import org.apache.commons.jxpath.ri.compiler.NodeTest;
28  import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
29  import org.apache.commons.jxpath.ri.model.NodeIterator;
30  import org.apache.commons.jxpath.ri.model.NodePointer;
31  import org.codehaus.plexus.util.StringUtils;
32  import org.codehaus.plexus.util.xml.Xpp3Dom;
33  
34  /**
35   * A node iterator for JXPath to support <code>Xpp3Dom</code>.
36   * 
37   * @author Benjamin Bentmann
38   * @version $Id: Xpp3DomNodeIterator.java 1035671 2010-11-16 16:04:51Z bentmann $
39   */
40  class Xpp3DomNodeIterator
41      implements NodeIterator
42  {
43  
44      private NodePointer parent;
45  
46      private NodeTest test;
47  
48      private Xpp3Dom node;
49  
50      private Xpp3Dom[] children;
51  
52      private List<Xpp3Dom> filteredChildren = new ArrayList<Xpp3Dom>();
53  
54      private int filteredIndex;
55  
56      private Xpp3Dom child;
57  
58      private int position;
59  
60      public Xpp3DomNodeIterator( NodePointer parent, NodeTest test, boolean reverse, NodePointer startWith )
61      {
62          this.parent = parent;
63          this.node = (Xpp3Dom) parent.getNode();
64          this.children = this.node.getChildren();
65          if ( startWith != null )
66          {
67              for ( ; filteredIndex < children.length; filteredIndex++ )
68              {
69                  if ( startWith.equals( children[filteredIndex] ) )
70                  {
71                      filteredIndex++;
72                      break;
73                  }
74              }
75          }
76          this.test = test;
77          if ( reverse )
78          {
79              throw new UnsupportedOperationException();
80          }
81      }
82  
83      public NodePointer getNodePointer()
84      {
85          if ( position == 0 )
86          {
87              setPosition( 1 );
88          }
89          return ( child == null ) ? null : new Xpp3DomNodePointer( parent, child );
90      }
91  
92      public int getPosition()
93      {
94          return position;
95      }
96  
97      public boolean setPosition( int position )
98      {
99          this.position = position;
100         filterChildren( position );
101         child = ( position > 0 && position <= filteredChildren.size() ) ? filteredChildren.get( position - 1 ) : null;
102         return child != null;
103     }
104 
105     private void filterChildren( int position )
106     {
107         for ( ; position > filteredChildren.size() && filteredIndex < children.length; filteredIndex++ )
108         {
109             Xpp3Dom child = children[filteredIndex];
110             if ( testNode( child ) )
111             {
112                 filteredChildren.add( child );
113             }
114         }
115     }
116 
117     private boolean testNode( Xpp3Dom node )
118     {
119         if ( test == null )
120         {
121             return true;
122         }
123         if ( test instanceof NodeNameTest )
124         {
125             String nodeName = node.getName();
126             if ( StringUtils.isEmpty( nodeName ) )
127             {
128                 return false;
129             }
130 
131             NodeNameTest nodeNameTest = (NodeNameTest) test;
132             String namespaceURI = nodeNameTest.getNamespaceURI();
133             boolean wildcard = nodeNameTest.isWildcard();
134             String testName = nodeNameTest.getNodeName().getName();
135             String testPrefix = nodeNameTest.getNodeName().getPrefix();
136             if ( wildcard && testPrefix == null )
137             {
138                 return true;
139             }
140             if ( wildcard || testName.equals( nodeName ) )
141             {
142                 return StringUtils.isEmpty( namespaceURI ) || StringUtils.isEmpty( testPrefix );
143             }
144             return false;
145         }
146         if ( test instanceof NodeTypeTest )
147         {
148             switch ( ( (NodeTypeTest) test ).getNodeType() )
149             {
150                 case Compiler.NODE_TYPE_NODE:
151                     return true;
152                 case Compiler.NODE_TYPE_TEXT:
153                     return node.getValue() != null;
154                 default:
155                     return false;
156             }
157         }
158         return false;
159     }
160 
161 }