~ubuntu-branches/ubuntu/trusty/ivy/trusty

« back to all changes in this revision

Viewing changes to src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2009-03-06 22:04:56 UTC
  • Revision ID: james.westby@ubuntu.com-20090306220456-5v37luqiuqda8ewp
Tags: upstream-2.0.0
ImportĀ upstreamĀ versionĀ 2.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 *  contributor license agreements.  See the NOTICE file distributed with
 
4
 *  this work for additional information regarding copyright ownership.
 
5
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 
6
 *  (the "License"); you may not use this file except in compliance with
 
7
 *  the License.  You may obtain a copy of the License at
 
8
 *
 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
 
10
 *
 
11
 *  Unless required by applicable law or agreed to in writing, software
 
12
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
13
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
 *  See the License for the specific language governing permissions and
 
15
 *  limitations under the License.
 
16
 *
 
17
 */
 
18
package org.apache.ivy.plugins.parser;
 
19
 
 
20
import java.io.IOException;
 
21
import java.net.URL;
 
22
import java.text.ParseException;
 
23
import java.util.ArrayList;
 
24
import java.util.Date;
 
25
import java.util.HashSet;
 
26
import java.util.List;
 
27
import java.util.Set;
 
28
 
 
29
import org.apache.ivy.core.module.descriptor.Artifact;
 
30
import org.apache.ivy.core.module.descriptor.Configuration;
 
31
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
 
32
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
 
33
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
 
34
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
 
35
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 
36
import org.apache.ivy.core.module.id.ModuleRevisionId;
 
37
import org.apache.ivy.plugins.repository.Resource;
 
38
import org.apache.ivy.plugins.repository.ResourceHelper;
 
39
import org.apache.ivy.plugins.repository.url.URLResource;
 
40
import org.apache.ivy.util.Message;
 
41
import org.xml.sax.SAXException;
 
42
import org.xml.sax.SAXParseException;
 
43
import org.xml.sax.helpers.DefaultHandler;
 
44
 
 
45
public abstract class AbstractModuleDescriptorParser implements ModuleDescriptorParser {
 
46
    public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL,
 
47
            boolean validate) throws ParseException, IOException {
 
48
        return parseDescriptor(ivySettings, descriptorURL, 
 
49
            new URLResource(descriptorURL), validate);
 
50
    }
 
51
    
 
52
    public String getType() {
 
53
        return "ivy";
 
54
    }
 
55
    
 
56
    public Artifact getMetadataArtifact(ModuleRevisionId mrid, Resource res) {
 
57
        return DefaultArtifact.newIvyArtifact(mrid, new Date(res.getLastModified()));
 
58
    }
 
59
 
 
60
    protected abstract static class AbstractParser extends DefaultHandler {
 
61
        private static final String DEFAULT_CONF_MAPPING = "*->*";
 
62
 
 
63
        private String defaultConf; // used only as defaultconf, not used for
 
64
 
 
65
        // guesssing right side part of a mapping
 
66
        private String defaultConfMapping; // same as default conf but is used
 
67
 
 
68
        // for guesssing right side part of a mapping
 
69
        private DefaultDependencyDescriptor defaultConfMappingDescriptor;
 
70
 
 
71
        private Resource res;
 
72
 
 
73
        private List errors = new ArrayList();
 
74
 
 
75
        private DefaultModuleDescriptor md;
 
76
 
 
77
        private ModuleDescriptorParser parser;
 
78
 
 
79
        protected AbstractParser(ModuleDescriptorParser parser) {
 
80
            this.parser = parser;
 
81
        }
 
82
 
 
83
        public ModuleDescriptorParser getModuleDescriptorParser() {
 
84
            return parser;
 
85
        }
 
86
 
 
87
        protected void checkErrors() throws ParseException {
 
88
            if (!errors.isEmpty()) {
 
89
                throw new ParseException(errors.toString(), 0);
 
90
            }
 
91
        }
 
92
 
 
93
        public void setResource(Resource res) {
 
94
            this.res = res; // used for log and date only
 
95
            md = new DefaultModuleDescriptor(parser, res);
 
96
            md.setLastModified(ResourceHelper.getLastModifiedOrDefault(res));
 
97
        }
 
98
 
 
99
        protected Resource getResource() {
 
100
            return res;
 
101
        }
 
102
 
 
103
        protected String getDefaultConfMapping() {
 
104
            return defaultConfMapping;
 
105
        }
 
106
 
 
107
        protected void setDefaultConfMapping(String defaultConf) {
 
108
            defaultConfMapping = defaultConf;
 
109
        }
 
110
 
 
111
        protected void parseDepsConfs(String confs, DefaultDependencyDescriptor dd) {
 
112
            parseDepsConfs(confs, dd, defaultConfMapping != null);
 
113
        }
 
114
 
 
115
        protected void parseDepsConfs(String confs, DefaultDependencyDescriptor dd,
 
116
                boolean useDefaultMappingToGuessRightOperande) {
 
117
            parseDepsConfs(confs, dd, useDefaultMappingToGuessRightOperande, true);
 
118
        }
 
119
 
 
120
        protected void parseDepsConfs(String confs, DefaultDependencyDescriptor dd,
 
121
                boolean useDefaultMappingToGuessRightOperande, boolean evaluateConditions) {
 
122
            if (confs == null) {
 
123
                return;
 
124
            }
 
125
 
 
126
            String[] conf = confs.split(";");
 
127
            parseDepsConfs(conf, dd, useDefaultMappingToGuessRightOperande, evaluateConditions);
 
128
        }
 
129
 
 
130
        protected void parseDepsConfs(String[] conf, DefaultDependencyDescriptor dd,
 
131
                boolean useDefaultMappingToGuessRightOperande) {
 
132
            parseDepsConfs(conf, dd, useDefaultMappingToGuessRightOperande, true);
 
133
        }
 
134
 
 
135
        protected void parseDepsConfs(String[] conf, DefaultDependencyDescriptor dd,
 
136
                boolean useDefaultMappingToGuessRightOperande, boolean evaluateConditions) {
 
137
            replaceConfigurationWildcards(md);
 
138
            for (int i = 0; i < conf.length; i++) {
 
139
                String[] ops = conf[i].split("->");
 
140
                if (ops.length == 1) {
 
141
                    String[] modConfs = ops[0].split(",");
 
142
                    if (!useDefaultMappingToGuessRightOperande) {
 
143
                        for (int j = 0; j < modConfs.length; j++) {
 
144
                            dd.addDependencyConfiguration(modConfs[j].trim(), modConfs[j].trim());
 
145
                        }
 
146
                    } else {
 
147
                        for (int j = 0; j < modConfs.length; j++) {
 
148
                            String[] depConfs = getDefaultConfMappingDescriptor()
 
149
                                    .getDependencyConfigurations(modConfs[j]);
 
150
                            if (depConfs.length > 0) {
 
151
                                for (int k = 0; k < depConfs.length; k++) {
 
152
                                    String mappedDependency = evaluateConditions 
 
153
                                    ? evaluateCondition(depConfs[k].trim(), dd)
 
154
                                            : depConfs[k].trim();
 
155
                                    if (mappedDependency != null) {
 
156
                                        dd.addDependencyConfiguration(modConfs[j].trim(),
 
157
                                            mappedDependency);
 
158
                                    }
 
159
                                }
 
160
                            } else {
 
161
                                // no default mapping found for this configuration, map
 
162
                                // configuration to itself
 
163
                                dd.addDependencyConfiguration(modConfs[j].trim(), modConfs[j]
 
164
                                        .trim());
 
165
                            }
 
166
                        }
 
167
                    }
 
168
                } else if (ops.length == 2) {
 
169
                    String[] modConfs = ops[0].split(",");
 
170
                    String[] depConfs = ops[1].split(",");
 
171
                    for (int j = 0; j < modConfs.length; j++) {
 
172
                        for (int k = 0; k < depConfs.length; k++) {
 
173
                            String mappedDependency = evaluateConditions ? evaluateCondition(
 
174
                                depConfs[k].trim(), dd) : depConfs[k].trim();
 
175
                            if (mappedDependency != null) {
 
176
                                dd.addDependencyConfiguration(modConfs[j].trim(), mappedDependency);
 
177
                            }
 
178
                        }
 
179
                    }
 
180
                } else {
 
181
                    addError("invalid conf " + conf[i] + " for " + dd);
 
182
                }
 
183
            }
 
184
 
 
185
            if (md.isMappingOverride()) {
 
186
                addExtendingConfigurations(conf, dd, useDefaultMappingToGuessRightOperande);
 
187
            }
 
188
        }
 
189
 
 
190
        /**
 
191
         * Evaluate the optional condition in the given configuration, like "[org=MYORG]confX". If
 
192
         * the condition evaluates to true, the configuration is returned, if the condition
 
193
         * evaluatate to false, null is returned. If there are no conditions, the configuration
 
194
         * itself is returned.
 
195
         * 
 
196
         * @param conf
 
197
         *            the configuration to evaluate
 
198
         * @param dd
 
199
         *            the dependencydescriptor to which the configuration will be added
 
200
         * @return the evaluated condition
 
201
         */
 
202
        private String evaluateCondition(String conf, DefaultDependencyDescriptor dd) {
 
203
            if (conf.charAt(0) != '[') {
 
204
                return conf;
 
205
            }
 
206
 
 
207
            int endConditionIndex = conf.indexOf(']');
 
208
            if (endConditionIndex == -1) {
 
209
                addError("invalid conf " + conf + " for " + dd);
 
210
                return null;
 
211
            }
 
212
 
 
213
            String condition = conf.substring(1, endConditionIndex);
 
214
 
 
215
            int notEqualIndex = condition.indexOf("!=");
 
216
            if (notEqualIndex == -1) {
 
217
                int equalIndex = condition.indexOf('=');
 
218
                if (equalIndex == -1) {
 
219
                    addError("invalid conf " + conf + " for " + dd.getDependencyRevisionId());
 
220
                    return null;
 
221
                }
 
222
 
 
223
                String leftOp = condition.substring(0, equalIndex).trim();
 
224
                String rightOp = condition.substring(equalIndex + 1).trim();
 
225
 
 
226
                // allow organisation synonyms, like 'org' or 'organization'
 
227
                if (leftOp.equals("org") || leftOp.equals("organization")) {
 
228
                    leftOp = "organisation";
 
229
                }
 
230
 
 
231
                String attrValue = dd.getAttribute(leftOp);
 
232
                if (!rightOp.equals(attrValue)) {
 
233
                    return null;
 
234
                }
 
235
            } else {
 
236
                String leftOp = condition.substring(0, notEqualIndex).trim();
 
237
                String rightOp = condition.substring(notEqualIndex + 2).trim();
 
238
 
 
239
                // allow organisation synonyms, like 'org' or 'organization'
 
240
                if (leftOp.equals("org") || leftOp.equals("organization")) {
 
241
                    leftOp = "organisation";
 
242
                }
 
243
 
 
244
                String attrValue = dd.getAttribute(leftOp);
 
245
                if (rightOp.equals(attrValue)) {
 
246
                    return null;
 
247
                }
 
248
            }
 
249
 
 
250
            return conf.substring(endConditionIndex + 1);
 
251
        }
 
252
 
 
253
        private void addExtendingConfigurations(String[] confs, DefaultDependencyDescriptor dd,
 
254
                boolean useDefaultMappingToGuessRightOperande) {
 
255
            for (int i = 0; i < confs.length; i++) {
 
256
                addExtendingConfigurations(confs[i], dd, useDefaultMappingToGuessRightOperande);
 
257
            }
 
258
        }
 
259
 
 
260
        private void addExtendingConfigurations(String conf, DefaultDependencyDescriptor dd,
 
261
                boolean useDefaultMappingToGuessRightOperande) {
 
262
            Set configsToAdd = new HashSet();
 
263
            Configuration[] configs = md.getConfigurations();
 
264
            for (int i = 0; i < configs.length; i++) {
 
265
                String[] ext = configs[i].getExtends();
 
266
                for (int j = 0; j < ext.length; j++) {
 
267
                    if (conf.equals(ext[j])) {
 
268
                        String configName = configs[i].getName();
 
269
                        configsToAdd.add(configName);
 
270
                        addExtendingConfigurations(configName, dd,
 
271
                            useDefaultMappingToGuessRightOperande);
 
272
                    }
 
273
                }
 
274
            }
 
275
 
 
276
            String[] confs = (String[]) configsToAdd.toArray(new String[configsToAdd.size()]);
 
277
            parseDepsConfs(confs, dd, useDefaultMappingToGuessRightOperande);
 
278
        }
 
279
 
 
280
        protected DependencyDescriptor getDefaultConfMappingDescriptor() {
 
281
            if (defaultConfMappingDescriptor == null) {
 
282
                defaultConfMappingDescriptor = new DefaultDependencyDescriptor(ModuleRevisionId
 
283
                        .newInstance("", "", ""), false);
 
284
                parseDepsConfs(defaultConfMapping, defaultConfMappingDescriptor, false, false);
 
285
            }
 
286
            return defaultConfMappingDescriptor;
 
287
        }
 
288
 
 
289
        protected void addError(String msg) {
 
290
            if (res != null) {
 
291
                errors.add(msg + " in " + res + "\n");
 
292
            } else {
 
293
                errors.add(msg + "\n");
 
294
            }
 
295
        }
 
296
 
 
297
        public void warning(SAXParseException ex) {
 
298
            Message.warn("xml parsing: " + getLocationString(ex) + ": " + ex.getMessage());
 
299
        }
 
300
 
 
301
        public void error(SAXParseException ex) {
 
302
            addError("xml parsing: " + getLocationString(ex) + ": " + ex.getMessage());
 
303
        }
 
304
 
 
305
        public void fatalError(SAXParseException ex) throws SAXException {
 
306
            addError("[Fatal Error] " + getLocationString(ex) + ": " + ex.getMessage());
 
307
        }
 
308
 
 
309
        /** Returns a string of the location. */
 
310
        private String getLocationString(SAXParseException ex) {
 
311
            StringBuffer str = new StringBuffer();
 
312
 
 
313
            String systemId = ex.getSystemId();
 
314
            if (systemId != null) {
 
315
                int index = systemId.lastIndexOf('/');
 
316
                if (index != -1) {
 
317
                    systemId = systemId.substring(index + 1);
 
318
                }
 
319
                str.append(systemId);
 
320
            } else if (getResource() != null) {
 
321
                str.append(getResource().toString());
 
322
            }
 
323
            str.append(':');
 
324
            str.append(ex.getLineNumber());
 
325
            str.append(':');
 
326
            str.append(ex.getColumnNumber());
 
327
 
 
328
            return str.toString();
 
329
 
 
330
        } // getLocationString(SAXParseException):String
 
331
 
 
332
        protected String getDefaultConf() {
 
333
            return defaultConfMapping != null ? defaultConfMapping
 
334
                    : (defaultConf != null ? defaultConf : DEFAULT_CONF_MAPPING);
 
335
        }
 
336
 
 
337
        protected void setDefaultConf(String defaultConf) {
 
338
            this.defaultConf = defaultConf;
 
339
        }
 
340
 
 
341
        public ModuleDescriptor getModuleDescriptor() throws ParseException {
 
342
            checkErrors();
 
343
            return md;
 
344
        }
 
345
 
 
346
        protected Date getDefaultPubDate() {
 
347
            return new Date(md.getLastModified());
 
348
        }
 
349
 
 
350
        private void replaceConfigurationWildcards(ModuleDescriptor md) {
 
351
            Configuration[] configs = md.getConfigurations();
 
352
            for (int i = 0; i < configs.length; i++) {
 
353
                configs[i].replaceWildcards(md);
 
354
            }
 
355
        }
 
356
 
 
357
        protected void setMd(DefaultModuleDescriptor md) {
 
358
            this.md = md;
 
359
        }
 
360
 
 
361
        protected DefaultModuleDescriptor getMd() {
 
362
            return md;
 
363
        }
 
364
    }
 
365
 
 
366
}