This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 174846
Collapse All | Expand All

(-)3f43f5c29bc3 (+244 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.nbbuild;
41
42
import java.io.ByteArrayInputStream;
43
import java.io.File;
44
import java.io.FileOutputStream;
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.io.OutputStream;
48
import java.net.URL;
49
import java.util.ArrayList;
50
import java.util.Enumeration;
51
import java.util.HashMap;
52
import java.util.List;
53
import java.util.Map;
54
import java.util.regex.Pattern;
55
import java.util.zip.ZipEntry;
56
import java.util.zip.ZipFile;
57
import javax.xml.parsers.SAXParser;
58
import javax.xml.parsers.SAXParserFactory;
59
import org.apache.tools.ant.BuildException;
60
import org.apache.tools.ant.Project;
61
import org.apache.tools.ant.Task;
62
import org.apache.tools.ant.taskdefs.Get;
63
import org.netbeans.nbbuild.AutoupdateCatalogParser.ModuleItem;
64
import org.xml.sax.Attributes;
65
import org.xml.sax.InputSource;
66
import org.xml.sax.SAXException;
67
import org.xml.sax.helpers.DefaultHandler;
68
69
/**
70
 *
71
 * @author Jaroslav Tulach <jtulach@netbeans.org>
72
 */
73
public class AutoUpdate extends Task {
74
    private List<Modules> modules = new ArrayList<Modules>();
75
    private File dir;
76
    private URL catalog;
77
78
    public void setUpdateCenter(URL u) {
79
        catalog = u;
80
    }
81
82
    public void setNetBeansDestDir(File dir) {
83
        this.dir = dir;
84
    }
85
86
    public Modules createModules() {
87
        final Modules m = new Modules();
88
        modules.add(m);
89
        return m;
90
    }
91
92
    @Override
93
    public void execute() throws BuildException {
94
        File[] arr = dir == null ? null : dir.listFiles();
95
        if (arr == null) {
96
            throw new BuildException("netbeans.dest.dir must existing be directory: " + dir);
97
        }
98
99
        Map<String,String> installed = findExistingModules(dir);
100
101
        // no userdir
102
        Map<String, ModuleItem> units = AutoupdateCatalogParser.getUpdateItems(catalog, catalog, this);
103
        for (ModuleItem uu : units.values()) {
104
            if (!matches(uu.getCodeName())) {
105
                continue;
106
            }
107
            log("found module: " + uu, Project.MSG_VERBOSE);
108
            String version = installed.get(uu.getCodeName());
109
            if (version != null && !uu.isNewerThan(version)) {
110
                log("Version " + version + " of " + uu.getCodeName() + " is up to date", Project.MSG_VERBOSE);
111
                continue;
112
            }
113
            if (version == null) {
114
                log(uu.getCodeName() + "not present, downloading version " + uu.getSpecVersion(), Project.MSG_INFO);
115
            } else {
116
                log("Version " + version + " of " + uu.getCodeName() + " needs update to " + uu.getSpecVersion(), Project.MSG_INFO);
117
            }
118
119
            byte[] bytes = new byte[4096];
120
            try {
121
                File f = File.createTempFile(uu.getCodeName().replace('.', '-'), ".nbm");
122
                f.deleteOnExit();
123
                Get get = new Get();
124
                get.setProject(getProject());
125
                get.setTaskName("get:" + uu.getCodeName());
126
                get.setSrc(uu.getURL());
127
                get.setDest(f);
128
                get.setVerbose(true);
129
                get.execute();
130
131
                File cluster = new File(dir, uu.targetcluster);
132
133
                ZipFile zf = new ZipFile(f);
134
                Enumeration<? extends ZipEntry> en = zf.entries();
135
                while (en.hasMoreElements()) {
136
                    ZipEntry zipEntry = en.nextElement();
137
                    if (!zipEntry.getName().startsWith("netbeans/")) {
138
                        continue;
139
                    }
140
                    if (zipEntry.getName().endsWith("/")) {
141
                        continue;
142
                    }
143
                    File trgt = new File(cluster, zipEntry.getName().substring(9).replace('/', File.separatorChar));
144
                    trgt.getParentFile().mkdirs();
145
                    log("Writing " + trgt, Project.MSG_VERBOSE);
146
147
                    InputStream is = zf.getInputStream(zipEntry);
148
                    OutputStream os = new FileOutputStream(trgt);
149
                    for (;;) {
150
                        int len = is.read(bytes);
151
                        if (len == -1) {
152
                            break;
153
                        }
154
                        os.write(bytes, 0, len);
155
                    }
156
                    is.close();
157
                    os.close();
158
                }
159
                
160
            } catch (IOException ex) {
161
                throw new BuildException(ex);
162
            }
163
        }
164
    }
165
166
    private boolean matches(String cnb) {
167
        String dash = cnb.replace('.', '-');
168
        for (Modules ps : modules) {
169
            if (ps.pattern.matcher(dash).matches()) {
170
                return true;
171
            }
172
        }
173
        return false;
174
    }
175
176
    private Map<String,String> findExistingModules(File dir) {
177
        Map<String,String> all = new HashMap<String, String>();
178
        for (File cluster : dir.listFiles()) {
179
            File mc = new File(new File(cluster, "config"), "Modules");
180
            final File[] arr = mc.listFiles();
181
            if (arr == null) {
182
                continue;
183
            }
184
            for (File m : arr) {
185
                try {
186
                    parseVersion(m, all);
187
                } catch (Exception ex) {
188
                    log("Cannot parse " + m, ex, Project.MSG_WARN);
189
                }
190
            }
191
        }
192
        return all;
193
    }
194
195
    private static void parseVersion(File config, final Map<String,String> toAdd) throws Exception {
196
        class P extends DefaultHandler {
197
            String name;
198
            StringBuilder text;
199
200
            @Override
201
            public void characters(char[] chars, int indx, int len) throws SAXException {
202
                if (text != null) {
203
                    text.append(chars, indx, len);
204
                }
205
            }
206
207
            @Override
208
            public void endElement(String string, String string1, String string2) throws SAXException {
209
                if (text != null) {
210
                    toAdd.put(name, text.toString());
211
                    text = null;
212
                }
213
            }
214
215
            @Override
216
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
217
                if ("module".equals(qName)) {
218
                    name = attributes.getValue("name");
219
                    return;
220
                }
221
                if ("param".equals(qName) && "specversion".equals(attributes.getValue("name"))) {
222
                    text = new StringBuilder();
223
                    return;
224
                }
225
            }
226
227
            @Override
228
            public InputSource resolveEntity(String string, String string1) throws IOException, SAXException {
229
                return new InputSource(new ByteArrayInputStream(new byte[0]));
230
            }
231
        }
232
        P p = new P();
233
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
234
        parser.parse(config, p);
235
    }
236
237
    public static final class Modules {
238
        Pattern pattern;
239
240
        public void setIncludes(String regExp) {
241
            pattern = Pattern.compile(regExp);
242
        }
243
    }
244
}
(-)3f43f5c29bc3 (+625 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * Contributor(s):
25
 *
26
 * The Original Software is NetBeans. The Initial Developer of the Original
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
28
 * Microsystems, Inc. All Rights Reserved.
29
 *
30
 * If you wish your version of this file to be governed by only the CDDL
31
 * or only the GPL Version 2, indicate your decision by adding
32
 * "[Contributor] elects to include this software in this distribution
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34
 * single choice of license, a recipient has the option to distribute
35
 * your version of this file under either the CDDL, the GPL Version 2 or
36
 * to extend the choice of license to its licensees as provided above.
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
38
 * Version 2 license, then the option applies only if the new code is
39
 * made subject to such option by the copyright holder.
40
 */
41
42
package org.netbeans.nbbuild;
43
44
import java.io.BufferedInputStream;
45
import java.io.ByteArrayInputStream;
46
import java.io.IOException;
47
import java.io.InputStream;
48
import java.net.MalformedURLException;
49
import java.net.URI;
50
import java.net.URISyntaxException;
51
import java.net.URL;
52
import java.text.DateFormat;
53
import java.text.ParseException;
54
import java.text.SimpleDateFormat;
55
import java.util.ArrayList;
56
import java.util.Collection;
57
import java.util.HashMap;
58
import java.util.List;
59
import java.util.Map;
60
import java.util.Stack;
61
import java.util.jar.Manifest;
62
import java.util.logging.Level;
63
import java.util.logging.Logger;
64
import java.util.zip.GZIPInputStream;
65
import javax.xml.parsers.SAXParser;
66
import javax.xml.parsers.SAXParserFactory;
67
import org.apache.tools.ant.Project;
68
import org.apache.tools.ant.Task;
69
import org.xml.sax.Attributes;
70
import org.xml.sax.EntityResolver;
71
import org.xml.sax.InputSource;
72
import org.xml.sax.SAXException;
73
import org.xml.sax.SAXParseException;
74
import org.xml.sax.helpers.DefaultHandler;
75
76
/**
77
 *
78
 * @author Jiri Rechtacek
79
 */
80
class AutoupdateCatalogParser extends DefaultHandler {
81
    private final Map<String, ModuleItem> items;
82
    private final URL provider;
83
    private final EntityResolver entityResolver;
84
    private final URI baseUri;
85
    
86
    private AutoupdateCatalogParser (Map<String, ModuleItem> items, URL provider, URI base) {
87
        this.items = items;
88
        this.provider = provider;
89
        this.entityResolver = newEntityResolver();
90
        this.baseUri = base;
91
    }
92
93
    private EntityResolver newEntityResolver () {
94
        return new EntityResolver() {
95
            public InputSource resolveEntity(String string, String string1) throws SAXException, IOException {
96
                return new InputSource(new ByteArrayInputStream(new byte[0]));
97
            }
98
        };
99
    }
100
101
    
102
    private static final Logger ERR = Logger.getLogger (AutoupdateCatalogParser.class.getName ());
103
    
104
    private static enum ELEMENTS {
105
        module_updates, module_group, notification, module, description,
106
        module_notification, external_package, manifest, l10n, license
107
    }
108
    
109
    private static final String MODULE_UPDATES_ATTR_TIMESTAMP = "timestamp"; // NOI18N
110
    
111
    private static final String MODULE_GROUP_ATTR_NAME = "name"; // NOI18N
112
    
113
    private static final String NOTIFICATION_ATTR_URL = "url"; // NOI18N
114
    
115
    private static final String LICENSE_ATTR_NAME = "name"; // NOI18N
116
    
117
    private static final String MODULE_ATTR_CODE_NAME_BASE = "codenamebase"; // NOI18N
118
    private static final String MODULE_ATTR_HOMEPAGE = "homepage"; // NOI18N
119
    private static final String MODULE_ATTR_DISTRIBUTION = "distribution"; // NOI18N
120
    private static final String MODULE_ATTR_DOWNLOAD_SIZE = "downloadsize"; // NOI18N
121
    private static final String MODULE_ATTR_NEEDS_RESTART = "needsrestart"; // NOI18N
122
    private static final String MODULE_ATTR_MODULE_AUTHOR = "moduleauthor"; // NOI18N
123
    private static final String MODULE_ATTR_RELEASE_DATE = "releasedate"; // NOI18N
124
    private static final String MODULE_ATTR_IS_GLOBAL = "global"; // NOI18N
125
    private static final String MODULE_ATTR_TARGET_CLUSTER = "targetcluster"; // NOI18N
126
    private static final String MODULE_ATTR_EAGER = "eager"; // NOI18N
127
    private static final String MODULE_ATTR_AUTOLOAD = "autoload"; // NOI18N
128
    private static final String MODULE_ATTR_LICENSE = "license"; // NOI18N
129
    private static final String LICENSE_ATTR_URL = "url"; // NOI18N
130
    
131
    private static final String MANIFEST_ATTR_SPECIFICATION_VERSION = "OpenIDE-Module-Specification-Version"; // NOI18N
132
    
133
    private static final String TIME_STAMP_FORMAT = "ss/mm/hh/dd/MM/yyyy"; // NOI18N
134
    
135
    private static final String L10N_ATTR_LOCALE = "langcode"; // NOI18N
136
    private static final String L10N_ATTR_BRANDING = "brandingcode"; // NOI18N
137
    private static final String L10N_ATTR_MODULE_SPECIFICATION = "module_spec_version"; // NOI18N
138
    private static final String L10N_ATTR_MODULE_MAJOR_VERSION = "module_major_version"; // NOI18N
139
    private static final String L10N_ATTR_LOCALIZED_MODULE_NAME = "OpenIDE-Module-Name"; // NOI18N
140
    private static final String L10N_ATTR_LOCALIZED_MODULE_DESCRIPTION = "OpenIDE-Module-Long-Description"; // NOI18N
141
    
142
    private static String GZIP_EXTENSION = ".gz"; // NOI18N
143
144
    private static Map<String, ModuleItem> cache;
145
    private static URI cacheURI;
146
    synchronized static Map<String, ModuleItem> getUpdateItems (URL url, URL provider, Task task) {
147
148
        Map<String, ModuleItem> items = new HashMap<String, ModuleItem> ();
149
        URI base;
150
        try {
151
            if (provider != null) {
152
                base = provider.toURI();
153
            } else {
154
                base = url.toURI();
155
            }
156
            if (cache != null && cacheURI.equals(base)) {
157
                task.log("Using existing module item cache " + base, Project.MSG_INFO);
158
                return cache;
159
            }
160
            task.log("Downloading " + base, Project.MSG_INFO);
161
            InputSource is = null;
162
            try {
163
                SAXParserFactory factory = SAXParserFactory.newInstance();
164
                factory.setValidating(true);
165
                SAXParser saxParser = factory.newSAXParser();
166
                is = getInputSource(url, provider, base);
167
                saxParser.parse(is, new AutoupdateCatalogParser(items, provider, base));
168
                cacheURI = base;
169
                cache = items;
170
            } catch (Exception ex) {
171
                ERR.log(Level.INFO, "Failed to parse " + base, ex);
172
            } finally {
173
                if (is != null && is.getByteStream() != null) {
174
                    try {
175
                        is.getByteStream().close();
176
                    } catch (IOException e) {
177
                    }
178
                }
179
            }
180
        } catch (URISyntaxException ex) {
181
            ERR.log(Level.INFO, null, ex);
182
        }
183
        return items;
184
    }
185
    
186
    private static boolean isGzip (URL url) {
187
        boolean res = false;
188
        if (url != null) {
189
            res = url.getPath ().toLowerCase ().endsWith (GZIP_EXTENSION);
190
            ERR.log (Level.FINER, "Is GZIP " + url + " ? " + res);
191
        } else {
192
            ERR.log (Level.WARNING, "AutoupdateCatalogProvider has not URL.");
193
        }
194
        return res;
195
    }
196
    
197
    private static InputSource getInputSource(URL toParse, URL p, URI base) {
198
        InputStream is = null;
199
        try {            
200
            is = toParse.openStream ();
201
            if (isGzip (p)) {
202
                try {
203
                    is = new GZIPInputStream(is);
204
                } catch (IOException e) {
205
                    ERR.log (Level.INFO,
206
                            "The file at " + toParse +
207
                            ", corresponding to the catalog at " + p +
208
                            ", does not look like the gzip file, trying to parse it as the pure xml" , e);
209
                    //#150034
210
                    // Sometimes the .xml.gz file is downloaded as the pure .xml file due to the strange content-encoding processing
211
                    is.close();
212
                    is = null;
213
                    is = toParse.openStream();
214
                }
215
            }
216
            InputSource src = new InputSource(new BufferedInputStream (is));
217
            src.setSystemId(base.toString());
218
            return src;
219
        } catch (IOException ex) {
220
            if(is != null) {
221
                try {
222
                    is.close();
223
                } catch (IOException e) {
224
                }
225
            }
226
            ERR.log (Level.SEVERE, "Cannot estabilish input stream for " + toParse , ex);
227
            return new InputSource();
228
        }
229
    }
230
    
231
    private Stack<String> currentGroup = new Stack<String> ();
232
    private String catalogDate;
233
    private Stack<ModuleDescriptor> currentModule = new Stack<ModuleDescriptor> ();
234
    private Stack<Map <String,String>> currentLicense = new Stack<Map <String,String>> ();
235
    private Stack<String> currentNotificationUrl = new Stack<String> ();
236
    private List<String> lines = new ArrayList<String> ();
237
    private int bufferInitSize = 0;
238
239
    @Override
240
    public void characters (char[] ch, int start, int length) throws SAXException {
241
        lines.add (new String(ch, start, length));
242
        bufferInitSize += length;
243
    }
244
245
    @Override
246
    public void endElement (String uri, String localName, String qName) throws SAXException {
247
        switch (ELEMENTS.valueOf (qName)) {
248
            case module_updates :
249
                break;
250
            case module_group :
251
                assert ! currentGroup.empty () : "Premature end of module_group " + qName;
252
                currentGroup.pop ();
253
                break;
254
            case module :
255
                assert ! currentModule.empty () : "Premature end of module " + qName;
256
                currentModule.pop ();
257
                break;
258
            case l10n :
259
                break;
260
            case manifest :
261
                break;
262
            case description :
263
                ERR.info ("Not supported yet.");
264
                break;
265
            case notification :
266
                // write catalog notification
267
                if (this.provider != null && ! lines.isEmpty ()) {
268
                    StringBuffer sb = new StringBuffer (bufferInitSize);
269
                    for (String line : lines) {
270
                        sb.append (line);
271
                    }
272
                    String notification = sb.toString ();
273
                    String notificationUrl = currentNotificationUrl.peek ();
274
                    if (notificationUrl != null && notificationUrl.length () > 0) {
275
                        notification += (notification.length () > 0 ? "<br>" : "") + // NOI18N
276
                                "<a name=\"autoupdate_catalog_parser\" href=\"" + notificationUrl + "\">" + notificationUrl + "</a>"; // NOI18N
277
                    } else {
278
                        notification += (notification.length () > 0 ? "<br>" : "") +
279
                                "<a name=\"autoupdate_catalog_parser\"/>"; // NOI18N
280
                    }
281
                }
282
                currentNotificationUrl.pop ();
283
                break;
284
            case module_notification :
285
                // write module notification
286
                if (! lines.isEmpty ()) {
287
                    ModuleDescriptor md = currentModule.peek ();
288
                    assert md != null : "ModuleDescriptor found for " + provider;
289
                    StringBuffer buf = new StringBuffer (bufferInitSize);
290
                    for (String line : lines) {
291
                        buf.append (line);
292
                    }
293
                    md.appendNotification (buf.toString ());
294
                }
295
                break;
296
            case external_package :
297
                ERR.info ("Not supported yet.");
298
                break;
299
            case license :
300
                assert ! currentLicense.empty () : "Premature end of license " + qName;
301
                Map <String, String> curLic = currentLicense.peek ();
302
                String licenseName = curLic.keySet().iterator().next();
303
                Collection<String> values = curLic.values();
304
                String licenseUrl = (values.size() > 0) ? values.iterator().next() : null;
305
                
306
                currentLicense.pop ();
307
                break;
308
            default:
309
                ERR.warning ("Unknown element " + qName);
310
        }
311
    }
312
313
    @Override
314
    public void endDocument () throws SAXException {
315
        ERR.fine ("End parsing " + (provider == null ? "" : provider) + " at " + System.currentTimeMillis ());
316
    }
317
318
    @Override
319
    public void startDocument () throws SAXException {
320
        ERR.fine ("Start parsing " + (provider == null ? "" : provider) + " at " + System.currentTimeMillis ());
321
    }
322
323
    @Override
324
    public void startElement (String uri, String localName, String qName, Attributes attributes) throws SAXException {
325
        lines.clear();
326
        bufferInitSize = 0;
327
        switch (ELEMENTS.valueOf (qName)) {
328
            case module_updates :
329
                try {
330
                    catalogDate = "";
331
                    DateFormat format = new SimpleDateFormat (TIME_STAMP_FORMAT);
332
                    String timeStamp = attributes.getValue (MODULE_UPDATES_ATTR_TIMESTAMP);
333
                    if (timeStamp == null) {
334
                        ERR.info ("No timestamp is presented in " + (this.provider == null ? "" : this.provider));
335
                    } else {
336
                        //catalogDate = Utilities.formatDate (format.parse (timeStamp));
337
                        catalogDate = format.parse (timeStamp).toString();
338
                        ERR.finer ("Successfully read time " + timeStamp); // NOI18N
339
                    }
340
                } catch (ParseException pe) {
341
                    ERR.log (Level.INFO, null, pe);
342
                }
343
                break;
344
            case module_group :
345
                currentGroup.push (attributes.getValue (MODULE_GROUP_ATTR_NAME));
346
                break;
347
            case module :
348
                ModuleDescriptor md = ModuleDescriptor.getModuleDescriptor (
349
                        currentGroup.size () > 0 ? currentGroup.peek () : null, /* group */
350
                        baseUri, /* base URI */
351
                        this.catalogDate); /* catalog date */
352
                md.appendModuleAttributes (attributes);
353
                currentModule.push (md);
354
                break;
355
            case l10n :
356
                // construct l10n
357
                // XXX
358
                break;
359
            case manifest :
360
                
361
                // construct module
362
                ModuleDescriptor desc = currentModule.peek ();
363
                desc.appendManifest (attributes);
364
                ModuleItem m = desc.createUpdateItem ();
365
                
366
                // put module into UpdateItems
367
                items.put (desc.getId (), m);
368
                
369
                break;
370
            case description :
371
                ERR.info ("Not supported yet.");
372
                break;
373
            case module_notification :
374
                break;
375
            case notification :
376
                currentNotificationUrl.push (attributes.getValue (NOTIFICATION_ATTR_URL));
377
                break;
378
            case external_package :
379
                ERR.info ("Not supported yet.");
380
                break;
381
            case license :
382
                Map <String, String> map = new HashMap<String,String> ();
383
                map.put(attributes.getValue (LICENSE_ATTR_NAME), attributes.getValue (LICENSE_ATTR_URL));
384
                currentLicense.push (map);
385
                break;
386
            default:
387
                ERR.warning ("Unknown element " + qName);
388
        }
389
    }
390
391
    @Override
392
    public void warning(SAXParseException e) throws SAXException {
393
        parseError(e);
394
    }
395
396
    @Override
397
    public void error(SAXParseException e) throws SAXException {
398
        parseError(e);
399
    }
400
401
    @Override
402
    public void fatalError(SAXParseException e) throws SAXException {
403
        parseError(e);
404
    }
405
406
    private void parseError(SAXParseException e) {
407
        ERR.warning(e.getSystemId() + ":" + e.getLineNumber() + ":" + e.getColumnNumber() + ": " + e.getLocalizedMessage());
408
    }
409
410
    @Override
411
    public InputSource resolveEntity (String publicId, String systemId) throws IOException, SAXException {
412
        return entityResolver.resolveEntity (publicId, systemId);
413
    }
414
    
415
    private static class ModuleDescriptor {
416
        private String moduleCodeName;
417
        private URL distributionURL;
418
        private String targetcluster;
419
        private String homepage;
420
        private String downloadSize;
421
        private String author;
422
        private String publishDate;
423
        private String notification;
424
425
        private Boolean needsRestart;
426
        private Boolean isGlobal;
427
        private Boolean isEager;
428
        private Boolean isAutoload;
429
430
        private String specVersion;
431
        private Manifest mf;
432
        
433
        private String id;
434
435
        private String group;
436
        private URI base;
437
        private String catalogDate;
438
        
439
        private static ModuleDescriptor md = null;
440
        
441
        private ModuleDescriptor () {}
442
        
443
        public static ModuleDescriptor getModuleDescriptor (String group, URI base, String catalogDate) {
444
            if (md == null) {
445
                md = new ModuleDescriptor ();
446
            }
447
            
448
            md.group = group;
449
            md.base = base;
450
            md.catalogDate = catalogDate;
451
            
452
            return md;
453
        }
454
        
455
        public void appendModuleAttributes (Attributes module) {
456
            moduleCodeName = module.getValue (MODULE_ATTR_CODE_NAME_BASE);
457
            distributionURL = getDistribution (module.getValue (MODULE_ATTR_DISTRIBUTION), base);
458
            targetcluster = module.getValue (MODULE_ATTR_TARGET_CLUSTER);
459
            homepage = module.getValue (MODULE_ATTR_HOMEPAGE);
460
            downloadSize = module.getValue (MODULE_ATTR_DOWNLOAD_SIZE);
461
            author = module.getValue (MODULE_ATTR_MODULE_AUTHOR);
462
            publishDate = module.getValue (MODULE_ATTR_RELEASE_DATE);
463
            if (publishDate == null || publishDate.length () == 0) {
464
                publishDate = catalogDate;
465
            }
466
            String needsrestart = module.getValue (MODULE_ATTR_NEEDS_RESTART);
467
            String global = module.getValue (MODULE_ATTR_IS_GLOBAL);
468
            String eager = module.getValue (MODULE_ATTR_EAGER);
469
            String autoload = module.getValue (MODULE_ATTR_AUTOLOAD);
470
                        
471
            needsRestart = needsrestart == null || needsrestart.trim ().length () == 0 ? null : Boolean.valueOf (needsrestart);
472
            isGlobal = global == null || global.trim ().length () == 0 ? null : Boolean.valueOf (global);
473
            isEager = Boolean.parseBoolean (eager);
474
            isAutoload = Boolean.parseBoolean (autoload);
475
                        
476
            String licName = module.getValue (MODULE_ATTR_LICENSE);
477
        }
478
        
479
        public void appendManifest (Attributes manifest) {
480
            specVersion = manifest.getValue (MANIFEST_ATTR_SPECIFICATION_VERSION);
481
            mf = getManifest (manifest);
482
            id = moduleCodeName + '_' + specVersion; // NOI18N
483
        }
484
        
485
        public void appendNotification (String notification) {
486
            this.notification = notification;
487
        }
488
        
489
        public String getId () {
490
            return id;
491
        }
492
        
493
        public ModuleItem createUpdateItem () {
494
            ModuleItem res = ModuleItem.createModule (
495
                    moduleCodeName,
496
                    specVersion,
497
                    distributionURL,
498
                    author,
499
                    downloadSize,
500
                    homepage,
501
                    publishDate,
502
                    group,
503
                    mf,
504
                    isEager,
505
                    isAutoload,
506
                    needsRestart,
507
                    isGlobal,
508
                    targetcluster,
509
                    null);
510
            
511
            // clean-up ModuleDescriptor
512
            cleanUp ();
513
            
514
            return res;
515
        }
516
        
517
        private void cleanUp (){
518
            this.specVersion = null;
519
            this.mf = null;
520
            this.notification = null;
521
        }
522
    }
523
    
524
    private static URL getDistribution (String distribution, URI base) {
525
        URL retval = null;
526
        if (distribution != null && distribution.length () > 0) {
527
            try {
528
                URI distributionURI = new URI (distribution);
529
                if (! distributionURI.isAbsolute ()) {
530
                    if (base != null) {
531
                        distributionURI = base.resolve (distributionURI);
532
                    }
533
                }
534
                retval = distributionURI.toURL ();
535
            } catch (MalformedURLException ex) {
536
                ERR.log (Level.INFO, null, ex);
537
            } catch (URISyntaxException ex) {
538
                ERR.log (Level.INFO, null, ex);
539
            }
540
        }
541
        return retval;
542
    }
543
544
    private static Manifest getManifest (Attributes attrList) {
545
        Manifest mf = new Manifest ();
546
        java.util.jar.Attributes mfAttrs = mf.getMainAttributes ();
547
548
        for (int i = 0; i < attrList.getLength (); i++) {
549
            mfAttrs.put (new java.util.jar.Attributes.Name (attrList.getQName (i)), attrList.getValue (i));
550
        }
551
        return mf;
552
    }
553
554
    public static final class ModuleItem {
555
        private final String moduleCodeName;
556
        private final String specVersion;
557
        private final URL distributionURL;
558
        public final String targetcluster;
559
560
        private ModuleItem(String moduleCodeName, String specVersion, URL distributionURL, String targetcluster) {
561
            this.moduleCodeName = moduleCodeName;
562
            this.specVersion = specVersion;
563
            this.distributionURL = distributionURL;
564
            this.targetcluster = targetcluster;
565
        }
566
567
568
569
        static ModuleItem createModule(
570
            String moduleCodeName,
571
            String specVersion,
572
            URL distributionURL,
573
            String author,
574
            String downloadSize,
575
            String homepage,
576
            String publishDate,
577
            String group,
578
            Manifest mf,
579
            Boolean eager,
580
            Boolean autoload,
581
            Boolean needsRestart,
582
            Boolean global,
583
            String targetcluster,
584
            Object object
585
        ) {
586
            return new ModuleItem(moduleCodeName, specVersion, distributionURL, targetcluster);
587
        }
588
589
        public String getCodeName() {
590
            return moduleCodeName;
591
        }
592
593
        String getSpecVersion() {
594
            return specVersion;
595
        }
596
597
        URL getURL() {
598
            return distributionURL;
599
        }
600
601
        @Override
602
        public String toString() {
603
            return "[" + moduleCodeName + "@" + specVersion + "(" + targetcluster + ") <- " + distributionURL + "]";
604
        }
605
606
        boolean isNewerThan(String version) {
607
            String[] mine = specVersion.split("\\.");
608
            String[] its = version.split("\\.");
609
610
            int min = Math.min(mine.length, its.length);
611
            for (int i = 0; i < min; i++) {
612
                int m = Integer.parseInt(mine[i]);
613
                int it = Integer.parseInt(its[i]);
614
615
                if (m > it) {
616
                    return true;
617
                }
618
                if (m < it) {
619
                    return false;
620
                }
621
            }
622
            return mine.length > its.length;
623
        }
624
    }
625
}
(-)a/nbbuild/build.xml (+15 lines)
Lines 160-165 Link Here
160
  
160
  
161
  <target name="all-installer" description="Dummy target for build system compatibility"/>
161
  <target name="all-installer" description="Dummy target for build system compatibility"/>
162
162
163
  <target name="update" depends="init" description="Downloads binaries from an update center">
164
      <pathconvert property="modules.fullpath" >
165
          <path>
166
              <dirset dir="${nb_all}" includes="${allmodules}" />
167
          </path>
168
          <mapper type="identity" />
169
      </pathconvert>
170
      
171
      <sortsuitemodules unsortedmodules="${modules.fullpath}" sortedmodulesproperty="modules.sorted"/>
172
173
      <subant-junit target="update" failonerror="true">
174
          <buildpath path="${modules.sorted}"/>
175
      </subant-junit>
176
  </target>
177
163
  <!-- build NBMs for selected modules -->
178
  <!-- build NBMs for selected modules -->
164
  <target name="build-nbms" depends="init" description="Build all NBMs, all modules have to be built before proceed">
179
  <target name="build-nbms" depends="init" description="Build all NBMs, all modules have to be built before proceed">
165
      <mkdir dir="nbms" />
180
      <mkdir dir="nbms" />
(-)a/nbbuild/default.xml (+3 lines)
Lines 87-92 Link Here
87
    <taskdef name="arch"
87
    <taskdef name="arch"
88
         classname="org.netbeans.nbbuild.Arch"
88
         classname="org.netbeans.nbbuild.Arch"
89
         classpath="${nb_all}/nbbuild/nbantext.jar"/>
89
         classpath="${nb_all}/nbbuild/nbantext.jar"/>
90
    <taskdef name="autoupdate"
91
         classname="org.netbeans.nbbuild.AutoUpdate"
92
         classpath="${nb_all}/nbbuild/nbantext.jar"/>
90
    <taskdef name="fixdependencies"
93
    <taskdef name="fixdependencies"
91
         classname="org.netbeans.nbbuild.FixDependencies"
94
         classname="org.netbeans.nbbuild.FixDependencies"
92
         classpath="${nb_all}/nbbuild/nbantext.jar"/>
95
         classpath="${nb_all}/nbbuild/nbantext.jar"/>
(-)a/nbbuild/templates/common.xml (+11 lines)
Lines 162-167 Link Here
162
        </uptodate>
162
        </uptodate>
163
    </target>
163
    </target>
164
164
165
    <target name="update" depends="init">
166
        <property name="autoupdate.url" value="http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastSuccessfulBuild/artifact/nbbuild/nbms/updates.xml.gz"/>
167
        <echo message="Updating: ${code.name.base.dashes}"/>
168
        <autoupdate
169
            updatecenter="${autoupdate.url}"
170
            netbeansdestdir="${netbeans.dest.dir}"
171
        >
172
            <modules includes="${code.name.base.dashes}"/>
173
        </autoupdate>
174
    </target>
175
165
    <target name="compile" depends="init,up-to-date" unless="is.jar.uptodate">
176
    <target name="compile" depends="init,up-to-date" unless="is.jar.uptodate">
166
        <mkdir dir="${build.classes.dir}"/>
177
        <mkdir dir="${build.classes.dir}"/>
167
        <depend srcdir="${src.dir}" destdir="${build.classes.dir}" cache="build/depcache">
178
        <depend srcdir="${src.dir}" destdir="${build.classes.dir}" cache="build/depcache">
(-)3f43f5c29bc3 (+247 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of either the GNU
7
 * General Public License Version 2 only ("GPL") or the Common
8
 * Development and Distribution License("CDDL") (collectively, the
9
 * "License"). You may not use this file except in compliance with the
10
 * License. You can obtain a copy of the License at
11
 * http://www.netbeans.org/cddl-gplv2.html
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
 * specific language governing permissions and limitations under the
14
 * License.  When distributing the software, include this License Header
15
 * Notice in each file and include the License file at
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
17
 * particular file as subject to the "Classpath" exception as provided
18
 * by Sun in the GPL Version 2 section of the License file that
19
 * accompanied this code. If applicable, add the following below the
20
 * License Header, with the fields enclosed by brackets [] replaced by
21
 * your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.nbbuild;
41
42
import java.io.File;
43
import java.io.FileOutputStream;
44
import java.io.IOException;
45
import java.util.zip.ZipEntry;
46
import java.util.zip.ZipOutputStream;
47
import org.netbeans.junit.NbTestCase;
48
49
/**
50
 *
51
 * @author Jaroslav Tulach <jtulach@netbeans.org>
52
 */
53
public class AutoUpdateTest extends NbTestCase {
54
55
    public AutoUpdateTest(String name) {
56
        super(name);
57
    }
58
59
    public void testDownloadAndExtractModule() throws Exception {
60
        clearWorkDir();
61
62
        File f = new File(getWorkDir(), "org-netbeans-api-annotations-common.xml");
63
        PublicPackagesInProjectizedXMLTest.extractResource(f, "org-netbeans-api-annotations-common.xml");
64
65
        File nbm = generateNBM("org-netbeans-api-annotations-common.nbm",
66
            "netbeans/config/Modules/org-netbeans-api-annotations-common.xml",
67
            "netbeans/modules/org-netbeans-api-annotations-common.jar");
68
69
        File target = new File(getWorkDir(), "target");
70
        target.mkdirs();
71
72
        PublicPackagesInProjectizedXMLTest.execute(
73
            "autoupdate.xml", "-verbose", "-Durl=" + f.toURI().toURL(),
74
            "-Dincludes=org.netbeans.api.annotations.common",
75
            "-Dtarget=" + target
76
        );
77
78
        File xml = new File(
79
            new File(new File(new File(target, "platform11"), "config"), "Modules"),
80
            "org-netbeans-api-annotations-common.xml"
81
        );
82
        assertTrue("xml file created", xml.exists());
83
84
        File jar = new File(
85
            new File(new File(target, "platform11"), "modules"),
86
            "org-netbeans-api-annotations-common.jar"
87
        );
88
        assertTrue("jar file created", jar.exists());
89
    }
90
91
92
    public void testUpdateAlreadyInstalled() throws Exception {
93
        clearWorkDir();
94
95
        File f = new File(getWorkDir(), "org-netbeans-api-annotations-common.xml");
96
        PublicPackagesInProjectizedXMLTest.extractResource(f, "org-netbeans-api-annotations-common.xml");
97
98
        File nbm = generateNBM("org-netbeans-api-annotations-common.nbm",
99
            "netbeans/config/Modules/org-netbeans-api-annotations-common.xml",
100
            "netbeans/modules/org-netbeans-api-annotations-common.jar");
101
102
        File target = new File(getWorkDir(), "target");
103
        target.mkdirs();
104
        File m = new File(
105
            new File(new File(target, "platform11"), "modules"),
106
            "org-netbeans-api-annotations-common.jar"
107
        );
108
        m.getParentFile().mkdirs();
109
        m.createNewFile();
110
111
        File x = new File(
112
            new File(new File(new File(target, "platform11"), "config"), "Modules"),
113
            "org-netbeans-api-annotations-common.xml"
114
        );
115
        x.getParentFile().mkdirs();
116
        String txtx =
117
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
118
"<!DOCTYPE module PUBLIC \"-//NetBeans//DTD Module Status 1.0//EN\"\n" +
119
"                        \"http://www.netbeans.org/dtds/module-status-1_0.dtd\">\n" +
120
"<module name=\"org.netbeans.api.annotations.common\">\n" +
121
"    <param name=\"autoload\">true</param>\n" +
122
"    <param name=\"eager\">false</param>\n" +
123
"    <param name=\"jar\">modules/org-netbeans-api-annotations-common.jar</param>\n" +
124
"    <param name=\"release\">1</param>\n" +
125
"    <param name=\"reloadable\">false</param>\n" +
126
"    <param name=\"specversion\">1.3</param>\n" +
127
"</module>\n";
128
129
130
        FileOutputStream osx = new FileOutputStream(x);
131
        osx.write(txtx.getBytes());
132
        osx.close();
133
134
135
        PublicPackagesInProjectizedXMLTest.execute(
136
            "autoupdate.xml", "-verbose", "-Durl=" + f.toURI().toURL(),
137
            "-Dincludes=org.netbeans.api.annotations.common",
138
            "-Dtarget=" + target
139
        );
140
141
        File xml = new File(
142
            new File(new File(new File(target, "platform11"), "config"), "Modules"),
143
            "org-netbeans-api-annotations-common.xml"
144
        );
145
        assertTrue("xml file created", xml.exists());
146
147
        File jar = new File(
148
            new File(new File(target, "platform11"), "modules"),
149
            "org-netbeans-api-annotations-common.jar"
150
        );
151
        assertTrue("jar file created", jar.exists());
152
153
        if (PublicPackagesInProjectizedXMLTest.getStdOut().contains("Writing ")) {
154
            fail("No writes, the module is already installed:\n" + PublicPackagesInProjectizedXMLTest.getStdOut());
155
        }
156
    }
157
158
    public void testUpdateAlreadyInstalledAndOld() throws Exception {
159
        clearWorkDir();
160
161
        File f = new File(getWorkDir(), "org-netbeans-api-annotations-common.xml");
162
        PublicPackagesInProjectizedXMLTest.extractResource(f, "org-netbeans-api-annotations-common.xml");
163
164
        File nbm = generateNBM("org-netbeans-api-annotations-common.nbm",
165
            "netbeans/config/Modules/org-netbeans-api-annotations-common.xml",
166
            "netbeans/modules/org-netbeans-api-annotations-common.jar");
167
168
        File target = new File(getWorkDir(), "target");
169
        target.mkdirs();
170
        File m = new File(
171
            new File(new File(target, "platform11"), "modules"),
172
            "org-netbeans-api-annotations-common.jar"
173
        );
174
        m.getParentFile().mkdirs();
175
        m.createNewFile();
176
177
        File x = new File(
178
            new File(new File(new File(target, "platform11"), "config"), "Modules"),
179
            "org-netbeans-api-annotations-common.xml"
180
        );
181
        x.getParentFile().mkdirs();
182
        String txtx =
183
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
184
"<!DOCTYPE module PUBLIC \"-//NetBeans//DTD Module Status 1.0//EN\"\n" +
185
"                        \"http://www.netbeans.org/dtds/module-status-1_0.dtd\">\n" +
186
"<module name=\"org.netbeans.api.annotations.common\">\n" +
187
"    <param name=\"autoload\">true</param>\n" +
188
"    <param name=\"eager\">false</param>\n" +
189
"    <param name=\"jar\">modules/org-netbeans-api-annotations-common.jar</param>\n" +
190
"    <param name=\"release\">1</param>\n" +
191
"    <param name=\"reloadable\">false</param>\n" +
192
"    <param name=\"specversion\">1.0.3</param>\n" +
193
"</module>\n";
194
195
196
        FileOutputStream osx = new FileOutputStream(x);
197
        osx.write(txtx.getBytes());
198
        osx.close();
199
200
        Thread.sleep(1000);
201
        long last = x.lastModified();
202
203
        PublicPackagesInProjectizedXMLTest.execute(
204
            "autoupdate.xml", "-verbose", "-Durl=" + f.toURI().toURL(),
205
            "-Dincludes=org.netbeans.api.annotations.common",
206
            "-Dtarget=" + target
207
        );
208
209
        File xml = new File(
210
            new File(new File(new File(target, "platform11"), "config"), "Modules"),
211
            "org-netbeans-api-annotations-common.xml"
212
        );
213
        assertTrue("xml file created", xml.exists());
214
215
        File jar = new File(
216
            new File(new File(target, "platform11"), "modules"),
217
            "org-netbeans-api-annotations-common.jar"
218
        );
219
        assertTrue("jar file created", jar.exists());
220
221
        if (!PublicPackagesInProjectizedXMLTest.getStdOut().contains("Writing ")) {
222
            fail("Writes should be there:\n" + PublicPackagesInProjectizedXMLTest.getStdOut());
223
        }
224
225
        if (last >= jar.lastModified()) {
226
            fail("Newer timestamp for " + jar);
227
        }
228
    }
229
230
    public File generateNBM (String name, String... files) throws IOException {
231
        File f = new File (getWorkDir (), name);
232
233
        ZipOutputStream os = new ZipOutputStream (new FileOutputStream (f));
234
        os.putNextEntry (new ZipEntry ("Info/info.xml"));
235
        os.write ("nothing".getBytes ());
236
        os.closeEntry ();
237
        for (String n : files) {
238
            os.putNextEntry(new ZipEntry(n));
239
            os.write("empty".getBytes());
240
            os.closeEntry();
241
        }
242
        os.close();
243
244
        return f;
245
    }
246
247
}
(-)a/nbbuild/test/unit/src/org/netbeans/nbbuild/PublicPackagesInProjectizedXMLTest.java (-5 / +7 lines)
Lines 216-226 Link Here
216
    }
216
    }
217
    
217
    
218
    final static File extractResource(String res) throws Exception {
218
    final static File extractResource(String res) throws Exception {
219
        File f = File.createTempFile("res", ".xml");
220
        f.deleteOnExit ();
221
        extractResource(f, res);
222
        return f;
223
    }
224
    static void extractResource(File f, String res) throws Exception {
219
        URL u = PublicPackagesInProjectizedXMLTest.class.getResource(res);
225
        URL u = PublicPackagesInProjectizedXMLTest.class.getResource(res);
220
        assertNotNull ("Resource should be found " + res, u);
226
        assertNotNull ("Resource should be found " + res, u);
221
        
227
        
222
        File f = File.createTempFile("res", ".xml");
223
        f.deleteOnExit ();
224
        
228
        
225
        FileOutputStream os = new FileOutputStream(f);
229
        FileOutputStream os = new FileOutputStream(f);
226
        InputStream is = u.openStream();
230
        InputStream is = u.openStream();
Lines 230-240 Link Here
230
            os.write (ch);
234
            os.write (ch);
231
        }
235
        }
232
        os.close ();
236
        os.close ();
233
            
234
        return f;
235
    }
237
    }
236
    
238
    
237
    final static void execute (String res, String[] args) throws Exception {
239
    final static void execute (String res, String... args) throws Exception {
238
        execute (extractResource (res), args);
240
        execute (extractResource (res), args);
239
    }
241
    }
240
    
242
    
(-)3f43f5c29bc3 (+16 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project name="changeme" default="all" basedir=".">
3
    <target name="all">
4
        <echo message="${root}"/>
5
6
        <taskdef classname="org.netbeans.nbbuild.AutoUpdate" name="autoupdate" classpath="${nb_all}/nbbuild/nbantext.jar"/>
7
8
        <autoupdate
9
            updatecenter="${url}"
10
            netbeansdestdir="${target}"
11
        >
12
            <modules includes="${includes}"/>
13
        </autoupdate>
14
        
15
    </target>
16
</project>
(-)3f43f5c29bc3 (+12 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8" ?>
2
3
<!DOCTYPE module_updates PUBLIC "-//NetBeans//DTD Autoupdate Catalog 2.6//EN" "http://www.netbeans.org/dtds/autoupdate-catalog-2_6.dtd">
4
<module_updates timestamp="46/00/08/13/11/2009">
5
6
7
<module autoload="true" codenamebase="org.netbeans.api.annotations.common" distribution="org-netbeans-api-annotations-common.nbm" downloadsize="18599" homepage="http://www.netbeans.org/" license="8B813426" moduleauthor="" needsrestart="false" releasedate="2009/11/13" targetcluster="platform11">
8
    <manifest AutoUpdate-Show-In-Client="false" OpenIDE-Module="org.netbeans.api.annotations.common/1" OpenIDE-Module-Implementation-Version="nbms-and-javadoc-4296-on-091113" OpenIDE-Module-Java-Dependencies="Java &gt; 1.5" OpenIDE-Module-Name="Common Annotations" OpenIDE-Module-Requires="org.openide.modules.ModuleFormat1" OpenIDE-Module-Specification-Version="1.3"/>
9
    
10
</module>
11
</module_updates>
12

Return to bug 174846