001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.xbean.osgi.bundle.util;
020    
021    import java.util.ArrayList;
022    import java.util.Dictionary;
023    import java.util.HashMap;
024    import java.util.List;
025    import java.util.Map;
026    import java.util.jar.Attributes;
027    import java.util.jar.Manifest;
028    
029    import org.apache.xbean.osgi.bundle.util.HeaderParser.HeaderElement;
030    import org.osgi.framework.Constants;
031    import org.osgi.framework.Version;
032    
033    /**
034     * @version $Rev: 937957 $, $Date: 2010-04-26 10:00:08 +0200 (lun. 26 avril 2010) $
035     */
036    public class BundleDescription  {
037    
038        private Map headers;
039        
040        public BundleDescription(Manifest manifest) {
041            this.headers = manifestToMap(manifest);
042        }
043        
044        public BundleDescription(Dictionary dictionary) {
045            this.headers = new DictionaryMap(dictionary);
046        }
047        
048        public BundleDescription(Map headers) {
049            this.headers = headers;
050        }
051       
052        /**
053         * Returns a list of packages that are listed in <i>Import-Package</i> header.
054         */
055        public List<ImportPackage> getImportPackage() {
056            String headerValue = (String) headers.get(Constants.IMPORT_PACKAGE);
057            List<ImportPackage> imports = new ArrayList<ImportPackage>();
058            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
059            for (HeaderElement element : elements) {
060                ImportPackage p = new ImportPackage(element.getName(), element.getAttributes(), element.getDirectives());
061                imports.add(p);
062            }
063            return imports;
064        }
065        
066        /**
067         * Returns a list of packages that are listed in <i>Export-Package</i> header.
068         */
069        public List<ExportPackage> getExportPackage() {
070            String headerValue = (String) headers.get(Constants.EXPORT_PACKAGE);
071            List<ExportPackage> exports = new ArrayList<ExportPackage>();
072            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
073            for (HeaderElement element : elements) {
074                ExportPackage p = new ExportPackage(element.getName(), element.getAttributes(), element.getDirectives());
075                exports.add(p);
076            }
077            return exports;        
078        }
079        
080        /**
081         * Returns a list of packages that are listed in <i>Import-Package</i> header
082         * and are <b>not</b> listed in <i>Export-Package</i> header.
083         */
084        public List<ImportPackage> getExternalImports() {
085            List<ImportPackage> imports = getImportPackage();
086            List<ExportPackage> exports = getExportPackage();
087            List<ImportPackage> realImports = new ArrayList<ImportPackage>();
088            for (ImportPackage p : imports) {
089                if (!isExported(exports, p)) {
090                    realImports.add(p);
091                }
092            }
093            return realImports;
094        }
095        
096        private static boolean isExported(List<ExportPackage> exports, ImportPackage p) {
097            for (ExportPackage export : exports) {            
098                if (export.getName().equals(p.getName())) {
099                    return true;
100                }
101            }
102            return false;
103        }
104        
105        /**
106         * Returns a list of bundle names that are listed in <i>Require-Bundle</i> header.
107         */
108        public List<RequireBundle> getRequireBundle() {
109            String headerValue = (String) headers.get(Constants.REQUIRE_BUNDLE);
110            List<RequireBundle> requireBundles = new ArrayList<RequireBundle>();
111            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
112            for (HeaderElement element : elements) {
113                RequireBundle p = new RequireBundle(element.getName(), element.getAttributes(), element.getDirectives());
114                requireBundles.add(p);
115            }
116            return requireBundles;   
117        }
118        
119        /**
120         * Returns <i>Fragment-Host</i> header.
121         */
122        public FragmentHost getFragmentHost() {
123            String headerValue = (String) headers.get(Constants.FRAGMENT_HOST);
124            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
125            if (elements.size() == 1) {
126                HeaderElement element = elements.get(0);
127                return new FragmentHost(element.getName(), element.getAttributes(), element.getDirectives());
128            }
129            return null;
130        }
131        
132        /**
133         * Returns a list of packages that are listed in <i>DynamicImport-Package</i> header.
134         */
135        public List<HeaderEntry> getDynamicImportPackage() {
136            String headerValue = (String) headers.get(Constants.DYNAMICIMPORT_PACKAGE);
137            return parseStandardHeader(headerValue);
138        }
139        
140        /**
141         * Returns a list of paths that are listed in <i>Bundle-ClassPath</i> header.
142         */
143        public List<HeaderEntry> getBundleClassPath() {
144            String headerValue = (String) headers.get(Constants.BUNDLE_CLASSPATH);
145            return parseStandardHeader(headerValue);
146        }
147        
148        public SymbolicName getSymbolicName() {
149            String headerValue = (String) headers.get(Constants.BUNDLE_SYMBOLICNAME);
150            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
151            if (elements.size() == 1) {
152                HeaderElement element = elements.get(0);
153                return new SymbolicName(element.getName(), element.getAttributes(), element.getDirectives());
154            }
155            return null;
156        }
157        
158        public Version getVersion() {
159            String headerValue = (String) headers.get(Constants.BUNDLE_VERSION);
160            return getVersionRange(headerValue).getLow();
161        }
162        
163        public Map getHeaders() {
164            return headers;
165        }
166        
167        private List<HeaderEntry> parseStandardHeader(String headerValue) {
168            List<HeaderEntry> imports = new ArrayList<HeaderEntry>();
169            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
170            for (HeaderElement element : elements) {
171                HeaderEntry p = new HeaderEntry(element.getName(), element.getAttributes(), element.getDirectives());
172                imports.add(p);
173            }
174            return imports;
175        }
176        
177        private static Map<String, String> manifestToMap(Manifest manifest) {
178            Attributes attributes = manifest.getMainAttributes();
179            Map<String, String> headers = new HashMap<String, String>();
180            for (Map.ement  color="green">097            for (ExportPackage export : exports) {            
098                if (export.getName().equals(p.getName())) {
099                    return true;
100                }
101            }
102            return false;
103        }
104        
105        /**
106         * Returns a list of bundle names that are listed in <i>Require-Bundle</i> header.
107         */
108        public List<RequireBundle> getRequireBundle() {
109            String headerValue = (String) headers.get(Constants.REQUIRE_BUNDLE);
110            List<RequireBundle> requireBundles = new ArrayList<RequireBundle>();
111            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
112            for (HeaderElement element : elements) {
113                RequireBundle p = new RequireBundle(element.getName(), element.getAttributes(), element.getDirectives());
114                requireBundles.add(p);
115            }
116            return requireBundles;   
117        }
118        
119        /**
120         * Returns <i>Fragment-Host</i> header.
121         */
122        public FragmentHost getFragmentHost() {
123            String headerValue = (String) headers.get(Constants.FRAGMENT_HOST);
124            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
125            if (elements.size() == 1) {
126                HeaderElement element = elements.get(0);
127                return new FragmentHost(element.getName(), element.getAttributes(), element.getDirectives());
128            }
129            return null;
130        }
131        
132        /**
133         * Returns a list of packages that are listed in <i>DynamicImport-Package</i> header.
134         */
135        public List<HeaderEntry> getDynamicImportPackage() {
136            String headerValue = (String) headers.get(Constants.DYNAMICIMPORT_PACKAGE);
137            return parseStandardHeader(headerValue);
138        }
139        
140        /**
141         * Returns a list of paths that are listed in <i>Bundle-ClassPath</i> header.
142         */
143        public List<HeaderEntry> getBundleClassPath() {
144            String headerValue = (String) headers.get(Constants.BUNDLE_CLASSPATH);
145            return parseStandardHeader(headerValue);
146        }
147        
148        public SymbolicName getSymbolicName() {
149            String headerValue = (String) headers.get(Constants.BUNDLE_SYMBOLICNAME);
150            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
151            if (elements.size() == 1) {
152                HeaderElement element = elements.get(0);
153                return new SymbolicName(element.getName(), element.getAttributes(), element.getDirectives());
154            }
155            return null;
156        }
157        
158        public Version getVersion() {
159            String headerValue = (String) headers.get(Constants.BUNDLE_VERSION);
160            return getVersionRange(headerValue).getLow();
161        }
162        
163        public Map getHeaders() {
164            return headers;
165        }
166        
167        private List<HeaderEntry> parseStandardHeader(String headerValue) {
168            List<HeaderEntry> imports = new ArrayList<HeaderEntry>();
169            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
170            for (HeaderElement element : elements) {
171                HeaderEntry p = new HeaderEntry(element.getName(), element.getAttributes(), element.getDirectives());
172                imports.add(p);
173            }
174            return imports;
175        }
176        
177        private static Map<String, String> manifestToMap(Manifest manifest) {
178            Attributes attributes = manifest.getMainAttributes();
179            Map<String, String> headers = new HashMap<String, String>();
180            for (Map.ement  color="green">097            for (ExportPackage export : exports) {            
098                if (export.getName().equals(p.getName())) {
099                    return true;
100                }
101            }
102            return false;
103        }
104        
105        /**
106         * Returns a list of bundle names that are listed in <i>Require-Bundle</i> header.
107         */
108        public List<RequireBundle> getRequireBundle() {
109            String headerValue = (String) headers.get(Constants.REQUIRE_BUNDLE);
110            List<RequireBundle> requireBundles = new ArrayList<RequireBundle>();
111            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
112            for (HeaderElement element : elements) {
113                RequireBundle p = new RequireBundle(element.getName(), element.getAttributes(), element.getDirectives());
114                requireBundles.add(p);
115            }
116            return requireBundles;   
117        }
118        
119        /**
120         * Returns <i>Fragment-Host</i> header.
121         */
122        public FragmentHost getFragmentHost() {
123            String headerValue = (String) headers.get(Constants.FRAGMENT_HOST);
124            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
125            if (elements.size() == 1) {
126                HeaderElement element = elements.get(0);
127                return new FragmentHost(element.getName(), element.getAttributes(), element.getDirectives());
128            }
129            return null;
130        }
131        
132        /**
133         * Returns a list of packages that are listed in <i>DynamicImport-Package</i> header.
134         */
135        public List<HeaderEntry> getDynamicImportPackage() {
136            String headerValue = (String) headers.get(Constants.DYNAMICIMPORT_PACKAGE);
137            return parseStandardHeader(headerValue);
138        }
139        
140        /**
141         * Returns a list of paths that are listed in <i>Bundle-ClassPath</i> header.
142         */
143        public List<HeaderEntry> getBundleClassPath() {
144            String headerValue = (String) headers.get(Constants.BUNDLE_CLASSPATH);
145            return parseStandardHeader(headerValue);
146        }
147        
148        public SymbolicName getSymbolicName() {
149            String headerValue = (String) headers.get(Constants.BUNDLE_SYMBOLICNAME);
150            List<HeaderElement> elements = HeaderParser.parseHeader(headerValue);
151            if (elements.size() == 1) {