blob: 2d4fbc683d21b94ff29485e3498e1d62298a7b0b [file] [log] [blame]
/*
* 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();
}
}