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    
020    
021    package org.apache.xbean.finder;
022    
023    import java.io.InputStream;
024    import java.net.URL;
025    import java.util.ArrayList;
026    import java.util.Collections;
027    import java.util.List;
028    import java.util.Map;
029    import java.util.Set;
030    import java.util.zip.ZipEntry;
031    
032    import org.apache.xbean.osgi.bundle.util.BundleResourceFinder;
033    import org.apache.xbean.osgi.bundle.util.BundleUtils;
034    import org.apache.xbean.osgi.bundle.util.ResourceDiscoveryFilter;
035    import org.osgi.framework.Bundle;
036    import org.osgi.service.packageadmin.PackageAdmin;
037    
038    /**
039     * @version $Rev: 1160131 $ $Date: 2011-08-22 15:07:20 +0800 (Mon, 22 Aug 2011) $
040     */
041    public class BundleAnnotationFinder extends AbstractFinder {
042        private final Bundle bundle;
043        private final Set<String> paths;
044    
045        public BundleAnnotationFinder(PackageAdmin packageAdmin, Bundle bundle) throws Exception {
046            this(packageAdmin, bundle, BundleResourceFinder.FULL_DISCOVERY_FILTER);
047        }
048    
049        public BundleAnnotationFinder(PackageAdmin packageAdmin, Bundle bundle, ResourceDiscoveryFilter discoveryFilter) throws Exception {
050            this(packageAdmin, bundle, discoveryFilter, Collections.<String>emptySet());
051        }
052    
053        public BundleAnnotationFinder(PackageAdmin packageAdmin, Bundle bundle, ResourceDiscoveryFilter discoveryFilter, Set<String> paths) throws Exception {
054            this.bundle = BundleUtils.unwrapBundle(bundle);
055            BundleResourceFinder bundleResourceFinder = new BundleResourceFinder(packageAdmin, this.bundle, "", ".class", discoveryFilter);
056            bundleResourceFinder.find(new AnnotationFindingCallback());
057            this.paths = paths;
058        }
059    
060        @Override
061        protected URL getResource(String s) {
062            return bundle.getResource(s);
063        }
064    
065        @Override
066        protected Class<?> loadClass(String s) throws ClassNotFoundException {
067            return bundle.loadClass(s);
068        }
069    
070        @Override
071        public List<String> getAnnotatedClassNames() {
072            List<String> classNames = new ArrayList<String>(originalInfos.size());
073            for (Map.Entry<String, ClassInfo> entry: originalInfos.entrySet()) {
074                if (paths.contains(entry.getValue().getPath())) {
075                    classNames.add(entry.getKey());
076                }
077            }
078            return classNames;
079        }
080    
081        private class AnnotationFindingCallback implements BundleResourceFinder.ResourceFinderCallback {
082          
083            public boolean foundInDirectory(Bundle bundle, String baseDir, URL url) throws Exception {
084                InputStream in = url.openStream();
085                try {
086                    readClassDef(in, baseDir);
087                } finally {
088                    in.close();
089                }
090                return true;
091            }
092    
093           
094            public boolean foundInJar(Bundle bundle, String jarName, ZipEntry entry, InputStream in) throws Exception {
095                readClassDef(in, jarName);
096                return true;
097            }
098        }
099    
100    }