📄 bundlerepositoryserviceimpl.java
字号:
/* * Oscar Bundle Repository * Copyright (c) 2004, Richard S. Hall * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of the ungoverned.org nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Contact: Richard S. Hall (heavy@ungoverned.org) * Contributor(s): ***/package org.ungoverned.osgi.bundle.bundlerepository;import java.io.*;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import java.util.*;import kxml.sax.KXmlSAXParser;import org.osgi.framework.*;import org.osgi.service.packageadmin.ExportedPackage;import org.osgi.service.packageadmin.PackageAdmin;import org.ungoverned.osgi.service.bundlerepository.*;import fr.imag.adele.metadataparser.MultivalueMap;import fr.imag.adele.metadataparser.XmlCommonHandler;public class BundleRepositoryServiceImpl implements BundleRepositoryService{ private BundleContext m_context = null; private boolean m_initialized = false; private String[] m_urls = null; private List m_bundleList = new ArrayList(); private Map m_exportPackageMap = new HashMap(); private static final int EXPORT_PACKAGE_IDX = 0; private static final int EXPORT_BUNDLE_IDX = 1; private int m_hopCount = 1; private static final String[] DEFAULT_REPOSITORY_URL = { "http://oscar-osgi.sf.net/repository.xml" }; public static final String REPOSITORY_URL_PROP = "oscar.repository.url"; public static final String EXTERN_REPOSITORY_TAG = "extern-repositories"; public BundleRepositoryServiceImpl(BundleContext context) { m_context = context; String urlStr = context.getProperty(REPOSITORY_URL_PROP); if (urlStr != null) { StringTokenizer st = new StringTokenizer(urlStr); if (st.countTokens() > 0) { m_urls = new String[st.countTokens()]; for (int i = 0; i < m_urls.length; i++) { m_urls[i] = st.nextToken(); } } } // Use the default URL if none were specified. if (m_urls == null) { m_urls = DEFAULT_REPOSITORY_URL; } } public String[] getRepositoryURLs() { if (m_urls != null) { // Return a copy because the array is mutable. return (String[]) m_urls.clone(); } return null; } public synchronized void setRepositoryURLs(String[] urls) { if (urls != null) { m_urls = urls; initialize(); } } /** * Get the number of bundles available in the repository. * @return the number of available bundles. **/ public synchronized int getBundleRecordCount() { if (!m_initialized) { initialize(); } return m_bundleList.size(); } /** * Get the specified bundle record from the repository. * @param i the bundle record index to retrieve. * @return the associated bundle record or <tt>null</tt>. **/ public synchronized BundleRecord getBundleRecord(int i) { if (!m_initialized) { initialize(); } if ((i < 0) || (i >= getBundleRecordCount())) { return null; } return (BundleRecord) m_bundleList.get(i); } /** * Get bundle record for the bundle with the specified name * and version from the repository. * @param name the bundle record name to retrieve. * @param version three-interger array of the version associated with * the name to retrieve. * @return the associated bundle record or <tt>null</tt>. **/ public synchronized BundleRecord getBundleRecord(String name, int[] version) { if (!m_initialized) { initialize(); } BundleRecord[] records = getBundleRecords(name); if (records.length > 0) { for (int i = 0; i < records.length; i++) { String targetName = (String) records[i].getAttribute(BundleRecord.BUNDLE_NAME); int[] targetVersion = Util.parseVersionString( (String) records[i].getAttribute(BundleRecord.BUNDLE_VERSION)); if ((targetName != null) && targetName.equalsIgnoreCase(name) && (Util.compareVersion(targetVersion, version) == 0)) { return records[i]; } } } return null; } /** * Get all versions of bundle records for the specified name * from the repository. * @param name the bundle record name to retrieve. * @return an array of all versions of bundle records having the * specified name or <tt>null</tt>. **/ public synchronized BundleRecord[] getBundleRecords(String name) { if (!m_initialized) { initialize(); } BundleRecord[] records = new BundleRecord[0]; for (int i = 0; i < m_bundleList.size(); i++) { String targetName = (String) getBundleRecord(i).getAttribute(BundleRecord.BUNDLE_NAME); if ((targetName != null) && targetName.equalsIgnoreCase(name)) { BundleRecord[] newRecords = new BundleRecord[records.length + 1]; System.arraycopy(records, 0, newRecords, 0, records.length); newRecords[records.length] = getBundleRecord(i); records = newRecords; } } return records; } public boolean deployBundle( PrintStream out, PrintStream err, String updateLocation, boolean isResolve, boolean isStart) { // List to hole bundles that need to be started. List startList = null; // The first thing to do is to see if the bundle to be // deployed is locally installed. If so, then we have to // check if an update is available for it. If no update // is available then we just return. NOTE: This is sort // of a hack that is necessary because the resolvePackages() // method doesn't do this sort of checking, so we have // to do it here first. Bundle localBundle = findLocalBundleByUpdate(updateLocation); if (localBundle != null) { if (!isUpdateAvailable(out, err, localBundle)) { out.println("No update available: " + Util.getBundleName(localBundle)); return false; } } // Find the appropriate bundle record in the repository, // then calculate the transitive closure of its dependencies. BundleRecord record = findBundleRecordByUpdate(updateLocation); if (record != null) { // This set will contain all bundles that must be // deployed as a result of deploying the target bundle; // use a list because this will keep everything in order. List deployList = new ArrayList(); // Add the target bundle to the set, since it will // ultimately be deployed as a result of this request. deployList.add(updateLocation); // If the resolve flag is set, then get its imports to // calculate the transitive closure of its dependencies. if (isResolve) { PackageDeclaration[] imports = (PackageDeclaration[]) record.getAttribute(BundleRecord.IMPORT_PACKAGE); try { resolvePackages(imports, deployList); } catch (ResolveException ex) { err.println("Resolve error: " + ex.getPackageDeclaration()); return false; } } // Now iterate through all bundles in the deploy list // in reverse order and deploy each; the order is not // so important, but by reversing them at least the // dependencies will be printed first and perhaps it // will avoid some ordering issues when we are starting // bundles. for (int i = deployList.size() - 1; i >= 0; i--) { String deployLocation = (String) deployList.get(i); // See if the bundle is locally installed, in which case // we will be performing an update. localBundle = findLocalBundleByUpdate(deployLocation); if (localBundle != null) { // Verify that the locally installed bundle has an // update available for it; if not, then ignore it. if (!isUpdateAvailable(out, err, localBundle)) { continue; } // Print out an "updating" message. if (!deployLocation.equals(updateLocation)) { out.print("Updating dependency: ");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -