View Javadoc

1   //
2   // $Revision: 5 $
3   // $LastChangedBy: mhanns $
4   // $Date: 2010-04-01 10:10:45 +0200 (Do, 01 Apr 2010) $
5   // $HeadURL:
6   // svn://localhost/winf-ps/trunk/repository/src/main/java/de/uni_leipzig/wifa/iwi/mr3/dao/impl/neo4j/SearchProcessor.java
7   // $
8   //
9   
10  package de.uni_leipzig.wifa.iwi.mr3.dao.neo4j.impl;
11  
12  import java.util.ArrayList;
13  import java.util.List;
14  
15  import org.eclipse.emf.ecore.EcorePackage;
16  import org.neo4j.api.core.Direction;
17  import org.neo4j.api.core.Node;
18  import org.neo4j.api.core.ReturnableEvaluator;
19  import org.neo4j.api.core.StopEvaluator;
20  import org.neo4j.api.core.Traverser.Order;
21  
22  import de.uni_leipzig.wifa.iwi.mr3.common.Match;
23  import de.uni_leipzig.wifa.iwi.mr3.common.Segment;
24  import de.uni_leipzig.wifa.iwi.mr3.dao.Constants;
25  import de.uni_leipzig.wifa.iwi.mr3.dao.SearchProcessor;
26  import de.uni_leipzig.wifa.iwi.mr3.dao.neo4j.EcoreRelationshipType;
27  
28  /**
29   * Search processor.
30   */
31  public class SearchProcessorImpl implements SearchProcessor
32  {
33    /** Neo4j helper. */
34    private NeoHelper helper;
35  
36    /**
37     * Setter.
38     * 
39     * @param helper
40     *          the helper to set
41     */
42    public void setHelper(final NeoHelper helper)
43    {
44      this.helper = helper;
45    }
46  
47    /**
48     * Processes a complete search over all direct and indirect instances of
49     * EObject.
50     *
51     * @param expression
52     *          Search expresion
53     * @param classifiers
54     *          Classifiers to search for
55     * @param isCaseSensitive
56     *          Case sensitive search
57     * @param isRegEx
58     *          Regular expression search
59     * @return array with found models
60     * @see de.uni_leipzig.wifa.iwi.mr3.dao.SearchProcessor#processCompleteSearch(java.lang.String,
61     *      java.lang.String[], boolean, boolean)
62     */
63    @Override
64    public Match[] processCompleteSearch(
65        final String expression,
66        final String[] classifiers,
67        final boolean isCaseSensitive,
68        final boolean isRegEx)
69    {
70      final List<Node> registry = new ArrayList<Node>();
71      final List<Match> matches = new ArrayList<Match>();
72  
73      final SearchReturnableEvaluator searchEvaluator = new SearchReturnableEvaluator(expression, isCaseSensitive, isRegEx);
74      for (final Node model : helper.getSubrefNodeChildren(EcoreRelationshipType.RESOURCES))
75      {
76        for (final Node target : model.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, searchEvaluator,
77            EcoreRelationshipType.CONTAINS, Direction.OUTGOING, EcoreRelationshipType.REFERENCES_AS_CONTAINMENT,
78            Direction.OUTGOING))
79        {
80          // jetzt haben wir alle gesuchten Nodes
81          buildTreePath(target, searchEvaluator.getMatchedValues(), registry, matches);
82        }
83      }
84      return matches.toArray(new Match[matches.size()]);
85    }
86  
87    /**
88     * Processes a partial search for instances of given classifiers.
89     *
90     * @param expression
91     *          Search expresion
92     * @param classifiers
93     *          Classifiers to search for
94     * @param isCaseSensitive
95     *          Case sensitive search
96     * @param isRegEx
97     *          Regular expression search
98     * @return array with found models
99     * @see de.uni_leipzig.wifa.iwi.mr3.dao.SearchProcessor#processPartialSearch(java.lang.String,
100    *      java.lang.String[], boolean, boolean)
101    */
102   @Override
103   public Match[] processPartialSearch(
104       final String expression,
105       final String[] classifiers,
106       final boolean isCaseSensitive,
107       final boolean isRegEx)
108   {
109     final List<Node> registry = new ArrayList<Node>();
110     final List<Match> matches = new ArrayList<Match>();
111 
112     final SearchReturnableEvaluator searchEvaluator = new SearchReturnableEvaluator(expression, isCaseSensitive, isRegEx);
113 
114     final Node ecore = helper.getModelNode(EcorePackage.eNS_URI);
115     for (final Node metaClass : ecore.traverse(Order.BREADTH_FIRST, StopEvaluator.DEPTH_ONE,
116         new ClassifiersReturnableEvaluator(classifiers), EcoreRelationshipType.CONTAINS, Direction.OUTGOING))
117     {
118       for (final Node eachMetaClass : metaClass.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH,
119           ReturnableEvaluator.ALL, EcoreRelationshipType.SUPER, Direction.INCOMING))
120       {
121         for (final Node target : eachMetaClass.traverse(Order.BREADTH_FIRST, StopEvaluator.DEPTH_ONE, searchEvaluator,
122             EcoreRelationshipType.INSTANCE, Direction.OUTGOING))
123         {
124           // jetzt haben wir alle gesuchten Nodes
125           buildTreePath(target, searchEvaluator.getMatchedValues(), registry, matches);
126         }
127       }
128     }
129     return matches.toArray(new Match[matches.size()]);
130   }
131 
132   /**
133    * Adds a tree path of a found model element to the tree paths array of this
134    * search processor.
135    * @param target
136    *          the node of the found model element
137    * @param matchedValues
138    *          the value of the found property
139    * @param registry
140    *          Node cache
141    * @param treePaths
142    *          Result container
143    */
144   private void buildTreePath(
145       final Node target,
146       final String[] matchedValues,
147       final List<Node> registry,
148       final List<Match> treePaths)
149   {
150     if (registry.contains(target))
151     {
152       return;
153     }
154     registry.add(target);
155 
156     for (final String value : matchedValues)
157     {
158       final Match match = new Match();
159 
160       if (!(target.hasProperty(Constants.PROPERTY_NAME) && value.equalsIgnoreCase((String) target
161           .getProperty(Constants.PROPERTY_NAME))))
162       {
163         final Segment matchedValue = new Segment();
164         matchedValue.setValue(value);
165 
166         match.addSegment(matchedValue);
167       }
168 
169       for (final Node pathSegment : target.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL,
170           EcoreRelationshipType.CONTAINS, Direction.INCOMING, EcoreRelationshipType.REFERENCES_AS_CONTAINMENT,
171           Direction.INCOMING))
172       {
173         final Segment segment = new Segment();
174 
175         final Node pathSegmentType =
176             pathSegment.hasRelationship(EcoreRelationshipType.INSTANCE, Direction.INCOMING) ? pathSegment
177                 .getSingleRelationship(EcoreRelationshipType.INSTANCE, Direction.INCOMING).getStartNode() : null;
178         segment.setType(getQualifiedName(pathSegmentType));
179         if (!pathSegment.hasRelationship(EcoreRelationshipType.CONTAINS, Direction.INCOMING)
180             && pathSegment.hasProperty(Constants.PROPERTY_NS_URI))
181         {
182           // if this segment is the model, set the nsUri as segment name
183           segment.setName((String) pathSegment.getProperty(Constants.PROPERTY_NS_URI));
184         }
185         else if (pathSegment.hasProperty(Constants.PROPERTY_NAME))
186         {
187           // if this segment has the name property, set its value as segment
188           // name
189           segment.setName((String) pathSegment.getProperty(Constants.PROPERTY_NAME));
190           // EClass from the ecore package is a special case
191           if (segment.getName().equals(EcorePackage.Literals.ECLASS.getName()))
192           {
193             segment.setType(EcorePackage.eNS_URI + "#//" + EcorePackage.Literals.ECLASS.getName());
194           }
195 
196         }
197         match.addSegment(segment);
198       }
199       treePaths.add(match);
200     }
201   }
202 
203   /**
204    * Determines a qualified name of the given (type) node.
205    *
206    * @param pathSegmentType
207    *          the node
208    * @return Qualified name
209    *         <p>
210    */
211   private String getQualifiedName(final Node pathSegmentType)
212   {
213     if (null == pathSegmentType)
214     {
215       return EcorePackage.eNS_URI + "#//" + EcorePackage.Literals.EOBJECT.getName();
216     }
217     final StringBuilder qualifiedName = new StringBuilder();
218     for (final Node containerPackage : pathSegmentType.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH,
219         ReturnableEvaluator.ALL, EcoreRelationshipType.CONTAINS, Direction.INCOMING))
220     {
221       if (containerPackage.hasProperty(Constants.PROPERTY_NS_URI))
222       {
223         qualifiedName.append((String) containerPackage.getProperty(Constants.PROPERTY_NS_URI));
224         break;
225       }
226     }
227     qualifiedName.append("#//").append(pathSegmentType.getProperty(Constants.PROPERTY_NAME));
228     return qualifiedName.toString();
229   }
230 }