blob: 53b5d678b478af8e8129be973a80222603148db6 [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.dm.resources;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Dictionary;
import java.util.Enumeration;
import org.osgi.framework.Bundle;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
public class BundleResourceRepository {
private final Bundle m_bundle;
public BundleResourceRepository(Bundle bundle) {
m_bundle = bundle;
}
public synchronized void addHandler(ServiceReference ref, ResourceHandler handler) {
String filter = (String) ref.getProperty("filter"); // "(&(repository=a)(path=b)(name=*.xml))"
Filter filterObject = null;
if (filter != null) {
try {
filterObject = FrameworkUtil.createFilter(filter);
}
catch (InvalidSyntaxException e) {
e.printStackTrace();
return;
}
}
Enumeration entries = m_bundle.findEntries("/", null, true);
while (entries.hasMoreElements()) {
EntryResource resource = new EntryResource(m_bundle, (URL) entries.nextElement());
if (filterObject == null || filterObject.match(resource)) {
handler.added(resource);
}
}
}
public synchronized void removeHandler(ServiceReference ref, ResourceHandler handler) {
String filter = (String) ref.getProperty("filter"); // "(&(repository=a)(path=b)(name=*.xml))"
Filter filterObject = null;
if (filter != null) {
try {
filterObject = FrameworkUtil.createFilter(filter);
}
catch (InvalidSyntaxException e) {
e.printStackTrace();
return;
}
}
Enumeration entries = m_bundle.findEntries("/", null, true);
while (entries.hasMoreElements()) {
EntryResource resource = new EntryResource(m_bundle, (URL) entries.nextElement());
if (filterObject == null || filterObject.match(resource)) {
handler.removed(resource);
}
}
}
static class EntryResource extends Dictionary implements Resource {
private final URL m_entry;
private final String m_id;
private final String m_repository;
private final String m_path;
private final String m_name;
private static Object[] m_keys;
private Object[] m_values;
public EntryResource(Bundle bundle, URL entry) {
m_entry = entry;
// TODO is this unique? can we have the same url in more than one repository?
m_id = m_entry.toString();
m_repository = bundle.getSymbolicName() + "_" + bundle.getHeaders().get("Bundle-Version");
String path = entry.getPath();
int i = path.lastIndexOf('/');
if (i == -1) {
m_path = "/";
m_name = path;
}
else {
if (path.length() > (i + 1)) {
m_path = path.substring(0, i);
m_name = path.substring(i + 1);
}
else {
m_path = path;
m_name = "";
}
}
}
public final String getID() {
return m_id;
}
public final String getName() {
return m_name;
}
public final String getPath() {
return m_path;
}
public final String getRepository() {
return m_repository;
}
public final InputStream openStream() throws IOException {
return m_entry.openStream();
}
public Enumeration elements() {
if (m_values == null) {
m_values = new Object[] { m_id, m_repository, m_path, m_name };
}
return new ArrayEnumeration(m_values);
}
public Object get(Object key) {
if (Resource.ID.equals(key)) {
return m_id;
}
else if (Resource.REPOSITORY.equals(key)) {
return m_repository;
}
else if (Resource.PATH.equals(key)) {
return m_path;
}
else if (Resource.NAME.equals(key)) {
return m_name;
}
return null;
}
public boolean isEmpty() {
return false;
}
public Enumeration keys() {
if (m_keys == null) {
m_keys = new Object[] { Resource.ID, Resource.REPOSITORY, Resource.PATH, Resource.NAME };
}
return new ArrayEnumeration(m_keys);
}
public Object put(Object key, Object value) {
return null;
}
public Object remove(Object key) {
return null;
}
public int size() {
return 4;
}
}
static class ArrayEnumeration implements Enumeration {
private int m_counter = 0;
private Object[] m_elements;
public ArrayEnumeration(Object[] array) {
m_elements = array;
}
public boolean hasMoreElements() {
return (m_counter < m_elements.length);
}
public Object nextElement() {
return m_elements[m_counter++];
}
}
}