View Javadoc
1   package org.codehaus.plexus.component.composition;
2   
3   /*
4    * Copyright 2001-2006 Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import junit.framework.TestCase;
20  import org.codehaus.plexus.component.repository.ComponentDescriptor;
21  import org.codehaus.plexus.component.repository.io.PlexusTools;
22  import org.codehaus.plexus.classworlds.ClassWorld;
23  import org.codehaus.plexus.classworlds.realm.ClassRealm;
24  
25  import java.util.List;
26  
27  /**
28   *
29   *
30   * @author Jason van Zyl
31   *
32   * @version $Id$
33   */
34  public abstract class AbstractCompositionResolverTest
35      extends TestCase           
36  {
37  
38      /**
39       *
40       * @return
41       */
42      protected abstract CompositionResolver getCompositionResolver();
43  
44  
45      // ------------------------------------------------------------------------
46      //
47      //     +-------+           +-------+
48      //     |  c1   | --------> |  c2   |
49      //     +-------+           +-------+
50      //         |
51      //         |
52      //         V
53      //     +-------+
54      //     |  c3   |
55      //     +-------+
56      //
57      // ------------------------------------------------------------------------
58      public void testSimpleComponentResolution()
59          throws Exception
60      {
61          String cc1 =
62              "<component>" +
63              "  <implementation>java.lang.String</implementation>" +
64              "  <role>c1</role>" +
65              "  <requirements>" +
66              "    <requirement>" +
67              "      <role>c2</role>" +
68              "   </requirement>" +
69              "    <requirement>" +
70              "      <role>c3</role>" +
71              "   </requirement>" +
72              "  </requirements>" +
73              "</component>";
74  
75          String cc2 =
76              "<component>" +
77              "  <implementation>java.lang.String</implementation>" +
78              "  <role>c2</role>" +
79              "</component>";
80  
81          String cc3 =
82              "<component>" +
83              "  <implementation>java.lang.String</implementation>" +
84              "  <role>c3</role>" +
85              "</component>";
86  
87          ClassWorld classWorld = new ClassWorld( "test", Thread.currentThread().getContextClassLoader() );
88          ClassRealm realm = classWorld.getRealm( "test" );
89  
90          CompositionResolver compositionResolver = getCompositionResolver();
91  
92          ComponentDescriptor<?> c1 = PlexusTools.buildComponentDescriptor( cc1, realm );
93  
94          ComponentDescriptor<?> c2 = PlexusTools.buildComponentDescriptor( cc2, realm );
95  
96          ComponentDescriptor<?> c3 = PlexusTools.buildComponentDescriptor( cc3, realm );
97  
98          compositionResolver.addComponentDescriptor( c1 );
99  
100         compositionResolver.addComponentDescriptor( c2 );
101 
102         compositionResolver.addComponentDescriptor( c3 );
103 
104         List dependencies = compositionResolver.getRequirements( c1.getRole(), c1.getRoleHint() );
105 
106         assertEquals( 2, dependencies.size() );
107 
108         assertTrue( dependencies.contains( c2.getRole() + CompositionResolver.SEPARATOR_CHAR + c2.getRoleHint() ) );
109 
110         assertTrue( dependencies.contains( c3.getRole() + CompositionResolver.SEPARATOR_CHAR + c2.getRoleHint() ) );
111 
112         assertEquals( 2, dependencies.size() );
113     }
114 
115     // ------------------------------------------------------------------------
116     //
117     //     +-------+           +-------+
118     //     |  c1   | --------> |  c2   |
119     //     +-------+           +-------+
120     //         |
121     //         |
122     //         V
123     //     +-------+           +-------+
124     //     |  c3   | --------> |  c4   |
125     //     +-------+           +-------+
126     //         |
127     //         |
128     //         V
129     //     +-------+
130     //     |  c5   |
131     //     +-------+
132     //
133     // ------------------------------------------------------------------------
134     public void testComplexComponentResolution()
135         throws Exception
136     {
137         String cc1 =
138             "<component>" +
139             "  <implementation>java.lang.String</implementation>" +
140             "  <role>c1</role>" +
141             "  <requirements>" +
142             "    <requirement>" +
143             "      <role>c2</role>" +
144             "   </requirement>" +
145             "   <requirement>" +
146             "      <role>c3</role>" +
147             "   </requirement>" +
148             "  </requirements>" +
149             "</component>";
150 
151         String cc2 =
152             "<component>" +
153             "  <implementation>java.lang.String</implementation>" +
154             "  <role>c2</role>" +
155             "</component>";
156 
157         String cc3 =
158             "<component>" +
159             "  <implementation>java.lang.String</implementation>" +
160             "  <role>c3</role>" +
161             "  <requirements>" +
162             "    <requirement>" +
163             "      <role>c4</role>" +
164             "   </requirement>" +
165             "    <requirement>" +
166             "      <role>c5</role>" +
167             "   </requirement>" +
168             "  </requirements>" +
169             "</component>";
170 
171         String cc4 =
172             "<component>" +
173             "  <implementation>java.lang.String</implementation>" +
174             "  <role>c4</role>" +
175             "</component>";
176 
177         String cc5 =
178             "<component>" +
179             "  <implementation>java.lang.String</implementation>" +
180             "  <role>c5</role>" +
181             "</component>";
182 
183         ClassWorld classWorld = new ClassWorld( "test", Thread.currentThread().getContextClassLoader() );
184         ClassRealm realm = classWorld.getRealm( "test" );
185 
186         CompositionResolver compositionResolver = getCompositionResolver();
187 
188         ComponentDescriptor<?> c1 = PlexusTools.buildComponentDescriptor( cc1, realm );
189 
190         ComponentDescriptor<?> c2 = PlexusTools.buildComponentDescriptor( cc2, realm );
191 
192         ComponentDescriptor<?> c3 = PlexusTools.buildComponentDescriptor( cc3, realm );
193 
194         ComponentDescriptor<?> c4 = PlexusTools.buildComponentDescriptor( cc4, realm );
195 
196         ComponentDescriptor<?> c5 = PlexusTools.buildComponentDescriptor( cc5, realm );
197 
198         compositionResolver.addComponentDescriptor( c1 );
199 
200         compositionResolver.addComponentDescriptor( c2 );
201 
202         compositionResolver.addComponentDescriptor( c3 );
203 
204         compositionResolver.addComponentDescriptor( c4 );
205 
206         compositionResolver.addComponentDescriptor( c5 );
207 
208         List dependencies = compositionResolver.getRequirements( c1.getRole(), c1.getRoleHint() );
209 
210         assertEquals( 2, dependencies.size() );
211 
212         // I just leave this at the moment as I am just 99% sure that this is not needed and not
213         // correct. compositionResolver.getComponentDependencies() should return only direct dependencies
214         //
215         // I will need to add a method like getSortedComponents()
216         // which will do topological sort of DAG and return list of ordered component which can be used
217         // by ComponentComposer.
218         // Possibility of checking if there are cycles probably also must be exposed in API (DAG has it alredy)
219         // and it should be used
220         // I can implement cycle detecting from single node (source) as after adding new component
221         // we don't have to probably check entire graph but we will probably have to check
222         // if there are cycles.
223 
224         /**
225         // c5 must come before c3
226         assertTrue( dependencies.indexOf( "c5" ) < dependencies.indexOf( "c3" ) );
227 
228         // c4 must come before c3
229         assertTrue( dependencies.indexOf( "c4" ) < dependencies.indexOf( "c3" ) );
230         */
231     }
232 }