/* * 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.felix.bundlerepository.impl; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import org.apache.felix.bundlerepository.Capability; import org.apache.felix.bundlerepository.Property; import org.apache.felix.bundlerepository.Repository; import org.apache.felix.bundlerepository.Requirement; import org.apache.felix.bundlerepository.Resource; import org.apache.felix.utils.version.VersionTable; import org.osgi.framework.Version; public class ResourceImpl implements Resource { private final Map m_map = new HashMap(); private final List m_capList = new ArrayList(); private final List m_reqList = new ArrayList(); private Repository m_repo; private Map m_uris; private transient int m_hash; public ResourceImpl() { } public boolean equals(Object o) { if (o instanceof Resource) { if (getSymbolicName() == null || getVersion() == null) { return this == o; } return getSymbolicName().equals(((Resource) o).getSymbolicName()) && getVersion().equals(((Resource) o).getVersion()); } return false; } public int hashCode() { if (m_hash == 0) { if (getSymbolicName() == null || getVersion() == null) { m_hash = super.hashCode(); } else { m_hash = getSymbolicName().hashCode() ^ getVersion().hashCode(); } } return m_hash; } public Repository getRepository() { return m_repo; } public void setRepository(Repository repository) { this.m_repo = repository; } public Map getProperties() { convertURIs(); return m_map; } public String getPresentationName() { String pres = (String) m_map.get(PRESENTATION_NAME); return (pres!=null && !pres.isEmpty())? pres : toString(); } public String getSymbolicName() { return (String) m_map.get(SYMBOLIC_NAME); } public String getId() { return (String) m_map.get(ID); } public Version getVersion() { Version v = (Version) m_map.get(VERSION); v = (v == null) ? Version.emptyVersion : v; return v; } public String getURI() { convertURIs(); return (String) m_map.get(Resource.URI); } public Long getSize() { Object sz = m_map.get(Resource.SIZE); if (sz instanceof Long) return ((Long) sz); long size = findResourceSize(); m_map.put(Resource.SIZE, size); return size; } private long findResourceSize() { String uri = getURI(); if (uri != null) { try { URL url = new URL(uri); if ("file".equals(url.getProtocol())) return new File(url.getFile()).length(); else return findResourceSize(url); } catch (Exception e) { // TODO should really log this... } } return -1L; } private long findResourceSize(URL url) throws IOException { byte[] bytes = new byte[8192]; // Not a File URL, stream the whole thing through to find out the size InputStream is = null; long fileSize = 0; try { is = url.openStream(); int length = 0; while ((length = is.read(bytes)) != -1) { fileSize += length; } } catch (Exception ex) { // should really log this... } finally { if (is != null) is.close(); } return fileSize; } public Requirement[] getRequirements() { return (Requirement[]) m_reqList.toArray(new Requirement[m_reqList.size()]); } public void addRequire(Requirement req) { m_reqList.add(req); } public Capability[] getCapabilities() { return (Capability[]) m_capList.toArray(new Capability[m_capList.size()]); } public void addCapability(Capability cap) { m_capList.add(cap); } public String[] getCategories() { List catList = (List) m_map.get(CATEGORY); if (catList == null) { return new String[0]; } return (String[]) catList.toArray(new String[catList.size()]); } public void addCategory(String category) { List catList = (List) m_map.get(CATEGORY); if (catList == null) { catList = new ArrayList(); m_map.put(CATEGORY, catList); } catList.add(category); } public boolean isLocal() { return false; } /** * Default setter method when setting parsed data from the XML file. **/ public Object put(Object key, Object value) { put(key.toString(), value.toString(), null); return null; } public void put(String key, String value, String type) { key = key.toLowerCase(); m_hash = 0; if (Property.URI.equals(type) || URI.equals(key)) { if (m_uris == null) { m_uris = new HashMap(); } m_uris.put(key, value); } else if (Property.VERSION.equals(type) || VERSION.equals(key)) { m_map.put(key, VersionTable.getVersion(value)); } else if (Property.LONG.equals(type) || SIZE.equals(key)) { m_map.put(key, Long.valueOf(value)); } else if (Property.SET.equals(type) || CATEGORY.equals(key)) { StringTokenizer st = new StringTokenizer(value, ","); Set s = new HashSet(); while (st.hasMoreTokens()) { s.add(st.nextToken().trim()); } m_map.put(key, s); } else { m_map.put(key, value); } } private void convertURIs() { if (m_uris != null) { for (Iterator it = m_uris.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); String val = (String) m_uris.get(key); m_map.put(key, resolveUri(val)); } m_uris = null; } } private String resolveUri(String uri) { try { if (m_repo != null && m_repo.getURI() != null) { return new URI(m_repo.getURI()).resolve(uri).toString(); } } catch (Throwable t) { } return uri; } public String toString() { return (getId() == null || getId().isEmpty())?getSymbolicName():getId(); } }