1 package org.codehaus.mojo.exec;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.beans.IntrospectionException;
23 import java.beans.PropertyDescriptor;
24 import java.io.File;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Properties;
31
32 import org.apache.maven.toolchain.MisconfiguredToolchainException;
33 import org.apache.maven.toolchain.RequirementMatcherFactory;
34 import org.apache.maven.toolchain.ToolchainFactory;
35 import org.apache.maven.toolchain.ToolchainPrivate;
36 import org.apache.maven.toolchain.model.ToolchainModel;
37 import org.codehaus.plexus.component.annotations.Component;
38 import org.codehaus.plexus.component.annotations.Requirement;
39 import org.codehaus.plexus.logging.Logger;
40 import org.codehaus.plexus.util.FileUtils;
41 import org.codehaus.plexus.util.xml.Xpp3Dom;
42
43
44
45
46
47
48 @Component( role = ToolchainFactory.class, hint = "paths" )
49 class PathsToolchainFactory
50 implements ToolchainFactory
51 {
52
53 @Requirement
54 private Logger logger;
55
56 public ToolchainPrivate createToolchain( final ToolchainModel model )
57 throws MisconfiguredToolchainException
58 {
59 if ( model == null )
60 return null;
61
62 final PathsToolchain pathsToolchain = new PathsToolchain( model, this.logger );
63 final Properties provides = this.getProvidesProperties( model );
64 for ( final Map.Entry<Object, Object> provide : provides.entrySet() )
65 {
66 final String key = (String) provide.getKey();
67 final String value = (String) provide.getValue();
68 if ( value == null )
69 throw new MisconfiguredToolchainException( "Provides token '" + key
70 + "' doesn't have any value configured." );
71
72 pathsToolchain.addProvideToken( key, RequirementMatcherFactory.createExactMatcher( value ) );
73 }
74
75 final Xpp3Dom config = (Xpp3Dom) model.getConfiguration();
76 if ( config == null )
77 return pathsToolchain;
78
79 final Xpp3Dom pathDom = config.getChild( "paths" );
80 if ( pathDom == null )
81 return pathsToolchain;
82
83 final Xpp3Dom[] pathDoms = pathDom.getChildren( "path" );
84 if ( pathDoms == null || pathDoms.length == 0 )
85 return pathsToolchain;
86
87 final List<String> paths = new ArrayList<String>( pathDoms.length );
88 for ( final Xpp3Dom pathdom : pathDoms )
89 {
90 final String pathString = pathdom.getValue();
91
92 if ( pathString == null )
93 throw new MisconfiguredToolchainException( "path element is empty" );
94
95 final String normalizedPath = FileUtils.normalize( pathString );
96 final File file = new File( normalizedPath );
97 if ( !file.exists() )
98 throw new MisconfiguredToolchainException( "Non-existing path '" + file.getAbsolutePath() + "'" );
99
100 paths.add( normalizedPath );
101 }
102
103 pathsToolchain.setPaths( paths );
104
105 return pathsToolchain;
106 }
107
108 public ToolchainPrivate createDefaultToolchain()
109 {
110 return null;
111 }
112
113 protected Properties getProvidesProperties( final ToolchainModel model )
114 {
115 final Object value = this.getBeanProperty( model, "provides" );
116
117 return value instanceof Properties ? (Properties) value : toProperties( (Xpp3Dom) value );
118 }
119
120 protected static Properties toProperties( final Xpp3Dom dom )
121 {
122 final Properties props = new Properties();
123
124 final Xpp3Dom[] children = dom.getChildren();
125 for ( final Xpp3Dom child : children )
126 props.put( child.getName(), child.getValue() );
127
128 return props;
129 }
130
131 protected Object getBeanProperty( final Object obj, final String property )
132 {
133 try
134 {
135 final Method method = new PropertyDescriptor( property, obj.getClass() ).getReadMethod();
136
137 return method.invoke( obj );
138 }
139 catch ( final IntrospectionException e )
140 {
141 throw new RuntimeException( "Incompatible toolchain API", e );
142 }
143 catch ( final IllegalAccessException e )
144 {
145 throw new RuntimeException( "Incompatible toolchain API", e );
146 }
147 catch ( final InvocationTargetException e )
148 {
149 final Throwable cause = e.getCause();
150
151 if ( cause instanceof RuntimeException )
152 throw (RuntimeException) cause;
153
154 throw new RuntimeException( "Incompatible toolchain API", e );
155 }
156 }
157 }