Package org.apache.geronimo.jasper.internal

Source Code of org.apache.geronimo.jasper.internal.TldRegistryImpl

/**
*  Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.apache.geronimo.jasper.internal;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.ZipEntry;

import org.apache.geronimo.jasper.TldProvider;
import org.apache.geronimo.jasper.TldRegistry;
import org.apache.geronimo.kernel.osgi.FrameworkUtils;
import org.apache.geronimo.system.configuration.DependencyManager;
import org.apache.xbean.osgi.bundle.util.BundleResourceFinder;
import org.apache.xbean.osgi.bundle.util.BundleUtils;
import org.apache.xbean.osgi.bundle.util.BundleResourceFinder.ResourceFinderCallback;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TldRegistryImpl implements TldRegistry, BundleTrackerCustomizer {

    private static final Logger LOGGER = LoggerFactory.getLogger(TldRegistryImpl.class);
   
    private Map<Bundle, Collection<TldProvider.TldEntry>> map = new ConcurrentHashMap<Bundle, Collection<TldProvider.TldEntry>>();
   
    private final BundleContext bundleContext;

    public TldRegistryImpl(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
    }
   
    public Collection<TldProvider.TldEntry> getTls() {
        List<TldProvider.TldEntry> allTlds = new ArrayList<TldProvider.TldEntry>();
        for (Collection<TldProvider.TldEntry> tlds : map.values()) {
            allTlds.addAll(tlds);
        }
        return allTlds;
    }
   
    public Collection<TldProvider.TldEntry> getTlds(Bundle bundle) {
        Collection<TldProvider.TldEntry> tlds = map.get(bundle);
        return (tlds == null) ? Collections.<TldProvider.TldEntry>emptyList() : tlds;
    }

    private Set<Bundle> getDependentBundles(Bundle bundle) {
        Set<Bundle> dependentBundles = new HashSet<Bundle>();
       
        // add in bundles from dependency manager
        ServiceReference serviceReference = bundleContext.getServiceReference(DependencyManager.class.getName());
        if (serviceReference != null) {
            DependencyManager dependencyManager = (DependencyManager) bundleContext.getService(serviceReference);
            try {
                dependentBundles.addAll(dependencyManager.getFullDependentBundles(bundle.getBundleId()));
            } finally {
                bundleContext.ungetService(serviceReference);
            }
        }
       
        // add in wired bundles if WAB       
        String contextPath = (String) bundle.getHeaders().get("Web-ContextPath");
        if (contextPath != null) {
            Set<Bundle> wiredBundles = BundleUtils.getWiredBundles(bundle);
            dependentBundles.addAll(wiredBundles);
        }

        return dependentBundles;
    }
   
    public Collection<TldProvider.TldEntry> getDependentTlds(Bundle bundle) {
        List<TldProvider.TldEntry> allTlds = new ArrayList<TldProvider.TldEntry>();
        Set<Bundle> dependentBundles = getDependentBundles(bundle);
        for (Bundle dependentBundle : dependentBundles) {
            Collection<TldProvider.TldEntry> tlds = map.get(dependentBundle);
            if (tlds != null) {
                allTlds.addAll(tlds);
            }
        }
        return allTlds;
    }
   
    @Override
    public Object addingBundle(Bundle bundle, BundleEvent event) {
        Collection<TldProvider.TldEntry> tlds = scanBundle(bundle);
        map.put(bundle, tlds);       
        return bundle;       
    }

    @Override
    public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
    }

    @Override
    public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
        map.remove(bundle);       
    }

    private Collection<TldProvider.TldEntry> scanBundle(Bundle bundle) {
        ServiceReference reference = bundleContext.getServiceReference(PackageAdmin.class.getName());
        PackageAdmin packageAdmin = (PackageAdmin) bundleContext.getService(reference);
        try {
            BundleResourceFinder resourceFinder = new BundleResourceFinder(packageAdmin, bundle, "META-INF/", ".tld");       
            TldResourceFinderCallback callback = new TldResourceFinderCallback();
            resourceFinder.find(callback);
            return callback.getTlds();
        } catch (Exception e) {
            LOGGER.warn("Error scanning bundle for JSP tag libraries", e);
            return Collections.emptyList();
        } finally {
            bundleContext.ungetService(reference);
        }
    }
   
    private static class TldResourceFinderCallback implements ResourceFinderCallback, TldProvider {

        private final List<TldProvider.TldEntry> tlds = new ArrayList<TldProvider.TldEntry>();

        private TldResourceFinderCallback() {
        }
       
        public Collection<TldProvider.TldEntry> getTlds() {
            return tlds;
        }
       
        public boolean foundInDirectory(Bundle bundle, String basePath, URL url) throws Exception {
            LOGGER.debug("Found {} TLD in bundle {}", url, bundle);
            URL jarURL = null;
            /*
             * Try to convert to jar: url if possible. Makes life easier for Japser.
             * See GERONIMO-6295.
             */
            URL convertedURL = FrameworkUtils.convertURL(url);
            if ("jar".equals(convertedURL.getProtocol())) {
                String urlString = convertedURL.toExternalForm();
                int pos = urlString.indexOf("!/");
                if (pos != -1) {
                    jarURL = new URL(urlString.substring(4 /* jar: */, pos));
                }
            }
            tlds.add(new TldProvider.TldEntry(bundle, url, jarURL));           
            return true;
        }

        public boolean foundInJar(Bundle bundle, String jarName, ZipEntry entry, InputStream in) throws Exception {
            URL jarURL = bundle.getEntry(jarName);
            URL url = new URL("jar:" + jarURL.toString() + "!/" + entry.getName());
            LOGGER.debug("Found {} TLD in bundle {}", url, bundle);
            tlds.add(new TldProvider.TldEntry(bundle, url, jarURL));
            return false;
        }
       
    }

}
TOP

Related Classes of org.apache.geronimo.jasper.internal.TldRegistryImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.