You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2013/04/02 16:53:35 UTC
svn commit: r1463576 [5/8] - in /ace/trunk:
org.apache.ace.client.repository.api/
org.apache.ace.client.repository.helper.base/
org.apache.ace.client.repository.helper.bundle/
org.apache.ace.client.repository.helper.configuration/
org.apache.ace.client...
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,588 @@
+package org.apache.ace.client.repository.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.ace.client.repository.Associatable;
+import org.apache.ace.client.repository.Association;
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.RepositoryUtil;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+/**
+ * Represents a value-object as is part of the repository.<br>
+ * It stores the 'member' values of the repository object, and allows putting tags on this object by using <code>put()</code>
+ * and <code>remove()</code>. It 'looks' like a dictionary to allow filtering of it, using an ldap filter.
+ */
+public class RepositoryObjectImpl<T extends RepositoryObject> extends Dictionary<String, Object> implements RepositoryObject, EventHandler {
+ private final Map<String, String> m_attributes = new HashMap<String, String>();
+ private final Map<String, String> m_tags = new HashMap<String, String>();
+ @SuppressWarnings("unchecked")
+ private final Map<Class, List<Association>> m_associations = new HashMap<Class, List<Association>>();
+ private final ChangeNotifier m_notifier;
+ private final String m_xmlNode;
+
+ private volatile boolean m_deleted = false;
+ private volatile boolean m_busy = false;
+
+ public RepositoryObjectImpl(ChangeNotifier notifier, String xmlNode) {
+ this((Map<String, String>) null, null, notifier, xmlNode);
+ }
+
+ public RepositoryObjectImpl(Map<String, String> attributes, ChangeNotifier notifier, String xmlNode) {
+ this(attributes, null, notifier, xmlNode);
+ }
+
+ public RepositoryObjectImpl(HierarchicalStreamReader reader, ChangeNotifier notifier, String xmlNode) {
+ this(readMap(reader), readMap(reader), notifier, xmlNode);
+ readCustom(reader);
+ }
+
+ public RepositoryObjectImpl(Map<String, String> attributes, Map<String, String> tags, ChangeNotifier notifier, String xmlNode) {
+ m_xmlNode = xmlNode;
+ if (attributes != null) {
+ m_attributes.putAll(attributes);
+ }
+ if (tags != null) {
+ m_tags.putAll(tags);
+ }
+ if (notifier == null) {
+ throw new IllegalArgumentException();
+ }
+ m_notifier = notifier;
+ }
+
+ protected void notifyChanged(Properties props) {
+ if (props == null) {
+ props = new Properties();
+ }
+ props.put(EVENT_ENTITY, this);
+ m_notifier.notifyChanged(TOPIC_CHANGED_SUFFIX, props, m_busy);
+ }
+
+ /**
+ * Returns an enumeration of the values in this object's dictionary.
+ */
+ @Override
+ public Enumeration<Object> elements() {
+ synchronized (m_attributes) {
+ return new ValuesEnumeration();
+ }
+ }
+
+ /**
+ * Gets the object associated with this key. Will return null when the key is not used; if the key is available for both the
+ * tags and the object's basic information, an array of two Strings will be returned.
+ */
+ @Override
+ public Object get(Object key) {
+ synchronized (m_attributes) {
+ String manifest = m_attributes.get(key);
+ String tag = m_tags.get(key);
+
+ if (manifest == null) {
+ return tag;
+ }
+ else if (tag == null) {
+ return manifest;
+ }
+ else {
+ return new String[] { tag, manifest };
+ }
+ }
+ }
+
+ /**
+ * Return whether the dictionary is empty.
+ */
+ @Override
+ public boolean isEmpty() {
+ synchronized (m_attributes) {
+ return m_attributes.isEmpty() && m_tags.isEmpty();
+ }
+ }
+
+ /**
+ * Returns an enumeration of the keys in this object.
+ */
+ @Override
+ public Enumeration<String> keys() {
+ synchronized (m_attributes) {
+ Set<String> keys = new HashSet<String>();
+ keys.addAll(m_attributes.keySet());
+ keys.addAll(m_tags.keySet());
+ return new KeysEnumeration(keys.iterator());
+ }
+ }
+
+ /**
+ * Unsupported operation.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object put(String key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Unsupported operation.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the number of keys in both this object's tags, and its 'member' keys.
+ */
+ @Override
+ public int size() {
+ synchronized (m_attributes) {
+ Set<String> keys = new HashSet<String>();
+ keys.addAll(m_attributes.keySet());
+ keys.addAll(m_tags.keySet());
+ return keys.size();
+ }
+ }
+
+ public String addAttribute(String key, String value) {
+ for (String s : getDefiningKeys()) {
+ if (s.equals(key)) {
+ throw new UnsupportedOperationException("The defining attribute " + key + " is not allowed to be changed.");
+ }
+ }
+ synchronized (m_attributes) {
+ ensureCurrent();
+ notifyChanged(null);
+ return m_attributes.put(key, value);
+ }
+ }
+
+ public String addTag(String key, String value) {
+ synchronized (m_attributes) {
+ ensureCurrent();
+ notifyChanged(null);
+ return m_tags.put(key, value);
+ }
+ }
+
+ public String getAttribute(String key) {
+ synchronized (m_attributes) {
+ return m_attributes.get(key);
+ }
+ }
+
+ public String getTag(String key) {
+ synchronized (m_attributes) {
+ return m_tags.get(key);
+ }
+ }
+
+ public Enumeration<String> getAttributeKeys() {
+ synchronized (m_attributes) {
+ return new KeysEnumeration(new HashSet<String>(m_attributes.keySet()).iterator());
+ }
+ }
+
+ public Dictionary<String, Object> getDictionary() {
+ return this;
+ }
+
+ public Enumeration<String> getTagKeys() {
+ synchronized (m_attributes) {
+ return new KeysEnumeration(new HashSet<String>(m_tags.keySet()).iterator());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void add(Association association, Class clazz) {
+ synchronized (m_associations) {
+ List<Association> associations = m_associations.get(clazz);
+ if (associations == null) {
+ associations = new ArrayList<Association>();
+ m_associations.put(clazz, associations);
+ }
+ associations.add(association);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void remove(Association association, Class clazz) {
+ synchronized (m_associations) {
+ List<Association> associations = m_associations.get(clazz);
+ if (associations != null) {
+ associations.remove(association);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public <A extends Associatable> List<A> getAssociations(Class<A> clazz) {
+ synchronized (m_associations) {
+ List<A> result = new ArrayList<A>();
+ List<Association> associations = m_associations.get(clazz);
+ if (associations != null) {
+ for (Association association : associations) {
+ List<A> otherSide = association.getTo(this);
+ if (otherSide != null) {
+ // If the other side is null, the association
+ // is not satisfied.
+ result.addAll(otherSide);
+ }
+ }
+ }
+ return result;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean isAssociated(Object obj, Class clazz) {
+ synchronized (m_associations) {
+ if (obj == null) {
+ return false;
+ }
+ List<Association> associations = m_associations.get(clazz);
+ if (associations != null) {
+ for (Association association : associations) {
+ if (association.getTo(this).contains(obj)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public <TA extends Associatable, A extends Association> List<A> getAssociationsWith(Associatable other, Class<TA> clazz, Class<A> associationType) {
+ List<A> result = new ArrayList<A>();
+ synchronized (m_associations) {
+ if (other == null) {
+ return result;
+ }
+ List<Association> associations = m_associations.get(clazz);
+ if (associations != null) {
+ for (Association association : associations) {
+ if (association.getTo(this).contains(other)) {
+ result.add((A) association);
+ }
+ }
+ }
+ return result;
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean equals(Object o) {
+ synchronized(m_attributes) {
+ if ((o == null) || !(getClass().isInstance(o))) {
+ return false;
+ }
+ if (m_attributes.size() == 0) {
+ return this == o;
+ }
+ for (String s : getDefiningKeys()) {
+ String ourAttribute = m_attributes.get(s);
+ String otherAttribute = (String) ((RepositoryObjectImpl) o).m_attributes.get(s);
+ if ((ourAttribute == null) && (otherAttribute != null)) {
+ return false;
+ }
+ else if ((ourAttribute != null) && (otherAttribute == null)) {
+ return false;
+ }
+ else if ((ourAttribute == null) && (otherAttribute == null)) {
+ continue;
+ }
+ else if (!otherAttribute.equals(ourAttribute)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Returns an array of keys which are considered to be defining for this object's
+ * attributes. The basic implementation just uses every key that is used; this
+ * function is intended to be overridden by deriving classes, providing a real
+ * set.
+ *
+ * Note that the array returned from this function should be read from only;
+ * writing to it will change the state of the object.
+ */
+ String[] getDefiningKeys() {
+ return m_attributes.keySet().toArray(new String[m_attributes.size()]);
+ }
+
+ @Override
+ public int hashCode() {
+ synchronized(m_attributes) {
+ return m_attributes.hashCode();
+ }
+ }
+
+ void marshal(HierarchicalStreamWriter writer) {
+ synchronized (m_attributes) {
+ writer.startNode(m_xmlNode);
+ writeMap(writer, m_attributes, "attributes");
+ writeMap(writer, m_tags, "tags");
+ writeCustom(writer);
+ writer.endNode();
+ }
+ }
+
+ /**
+ * This method is intended to be overridden by deriving classes, to read custom information
+ * from the XML representation of this object. This method should end with the writer at
+ * the same 'level' as before, that is, using equally many moveDown() and moveUp() calls.
+ * @param reader A reader to read from the XML stream.
+ */
+ protected void readCustom(HierarchicalStreamReader reader) {
+ // do nothing
+ }
+
+ /**
+ * This method is intended to be overridden by deriving classes, to write custom information
+ * to the XML representation of this object. This method should end with the writer at
+ * the same 'level' as before, that is, using equally many moveDown() and moveUp() calls.
+ * @param writer A writer to write to the XML stream.
+ */
+ protected void writeCustom(HierarchicalStreamWriter writer) {
+ // do nothing
+ }
+
+ static void writeMap(HierarchicalStreamWriter writer, Map<String, String> entries, String name) {
+ writer.startNode(name);
+ for (Map.Entry<String, String> entry : entries.entrySet()) {
+ if (entry.getKey() != null && entry.getValue() != null) {
+ // we only write values that have non null keys and values
+ writer.startNode(entry.getKey());
+ writer.setValue(entry.getValue());
+ writer.endNode();
+ }
+ }
+ writer.endNode();
+ }
+
+ static Map<String, String> readMap(HierarchicalStreamReader reader) {
+ reader.moveDown();
+ Map<String, String> result = new HashMap<String, String>();
+ while (reader.hasMoreChildren()) {
+ reader.moveDown();
+ result.put(reader.getNodeName(), reader.getValue());
+ reader.moveUp();
+ }
+ reader.moveUp();
+ return result;
+ }
+
+ /**
+ * Helper function to check the existence of keys in a map. Each attribute is required
+ * to be non-empty.
+ * @param attributes A map of attribute-value combinations.
+ * @param mandatory An array of attributes which have to be present in the map.
+ * @return <code>attributes</code> if this map meets the requirements. If not, <code>IllegalArgumentException</code>
+ * will be thrown.
+ */
+ static Map<String, String> checkAttributes(Map<String, String> attributes, String... mandatory) {
+ boolean[] booleans = new boolean[mandatory.length];
+ Arrays.fill(booleans, false);
+ return checkAttributes(attributes, mandatory, booleans);
+ }
+
+ /**
+ * Helper function to check the existence of keys in a map.
+ * @param attributes A map of attribute-value combinations.
+ * @param mandatory An array of attributes which have to be present in the map.
+ * @param emptyAttributeAllowed An array of booleans, indicating which of the attributes is allowed
+ * to be equal. Items in this array are matched by index on the elements in <code>mandatory</code>, so
+ * the length should be equal.
+ * @return <code>attributes</code> if this map meets the requirements. If not, <code>IllegalArgumentException</code>
+ * will be thrown.
+ */
+ static Map<String, String> checkAttributes(Map<String, String> attributes, String[] mandatory, boolean[] emptyAttributeAllowed) {
+ if (!(mandatory.length == emptyAttributeAllowed.length)) {
+ throw new IllegalArgumentException("The length of the mandatory- and the emptyAttributeAllow-array should be equal.");
+ }
+ for (int i = 0; i < mandatory.length; i++) {
+ String attribute = mandatory[i];
+ boolean emptyAllowed = emptyAttributeAllowed[i];
+ if (!attributes.containsKey(attribute)) {
+ throw new IllegalArgumentException(attribute + " is a mandatory attribute.");
+ }
+ else if ((!emptyAllowed) && (attributes.get(attribute).length() == 0)) {
+ throw new IllegalArgumentException(attribute + " is not allowed to be empty.");
+ }
+ }
+ return attributes;
+ }
+
+ public String getXmlNode() {
+ return m_xmlNode;
+ }
+
+ public void handleEvent(Event e) {
+ }
+
+ void setDeleted() {
+ m_deleted = true;
+ }
+
+ public boolean isDeleted() {
+ return m_deleted;
+ }
+
+ void ensureNotDeleted() {
+ if (isDeleted()) {
+ throw new IllegalStateException("This object is deleted, and should no longer be used.");
+ }
+ }
+
+ void setBusy(boolean busy) {
+ // setBusy should 'wait' until all altering operations have passed. To do so,
+ // it gets the locks for the other 'set' objects. Once it has all these locks,
+ // we are sure no thread is performing a set-action.
+ synchronized(m_associations) {
+ synchronized(m_attributes) {
+ if (m_busy && !busy) {
+ m_associations.notifyAll();
+ m_attributes.notifyAll();
+ }
+ m_busy = busy;
+ }
+ }
+ }
+
+ public boolean getBusy() {
+ return m_busy;
+ }
+
+ // NEVER CALL WITHOUT m_attributes lock
+ private void ensureNotBusy() {
+ boolean interrupted = false;
+ while (m_busy) {
+ try {
+ m_attributes.wait();
+ }
+ catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ void ensureCurrent() {
+ ensureNotDeleted();
+ ensureNotBusy();
+ }
+
+ public String getDefinition() {
+ StringBuilder result = new StringBuilder();
+
+ result.append(getXmlNode().replaceAll("\\\\", "\\\\\\\\").replaceAll("-", "\\-"));
+
+ for (String key : getDefiningKeys()) {
+ String value = getAttribute(key);
+ if (value != null) {
+ result.append("-")
+ .append(key.replaceAll("\\\\", "\\\\\\\\").replaceAll("-", "\\-").replaceAll("\\/", "/"))
+ .append("-")
+ .append(value.replaceAll("\\\\", "\\\\\\\\").replaceAll("-", "\\-").replaceAll("\\/", "/"));
+ // About the /: the forward slash will be used by the preference admin, but we don't want that.
+ }
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Creates a filter string for use in associations, optionally with some
+ * additional properties. The basic implementation will use all <code>getDefiningKeys</code>.
+ * @param properties Properties indicating specifics of the filter to be created.
+ * @return A string representation of a filter, for use in <code>Association</code>s.
+ */
+ public String getAssociationFilter(Map<String, String> properties) {
+ StringBuilder filter = new StringBuilder("(&");
+
+ for (String key : getDefiningKeys()) {
+ filter.append("(" + key + "=" + RepositoryUtil.escapeFilterValue(getAttribute(key)) + ")");
+ }
+
+ filter.append(")");
+
+ return filter.toString();
+ }
+
+ /**
+ * Determines the cardinality of this endpoint of an association, given
+ * the passed properties.
+ * @param properties Properties indicating specifics of this endpoint.
+ * @return The necessary cardinality.
+ */
+ public int getCardinality(Map<String, String> properties) {
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * Returns a <code>Comparator</code> for this type of object, suitable
+ * for the endpoint properties that are passed.
+ * @return A <code>Comparator</code> for this type of object
+ */
+ public Comparator<T> getComparator() {
+ return null;
+ }
+
+ /**
+ * Helper class that implements an enumeration for use in <code>keys()</code>.
+ */
+ private static class KeysEnumeration implements Enumeration<String> {
+ private final Iterator<String> m_iter;
+
+ public KeysEnumeration(Iterator<String> iter) {
+ m_iter = iter;
+ }
+
+ public boolean hasMoreElements() {
+ return m_iter.hasNext();
+ }
+
+ public String nextElement() {
+ return m_iter.next();
+ }
+ }
+
+ /**
+ * Helper class that implements an enumeration for use in <code>elements()</code>.
+ */
+ private class ValuesEnumeration implements Enumeration<Object> {
+ private final Enumeration<String> m_iter = keys();
+
+ public boolean hasMoreElements() {
+ return m_iter.hasMoreElements();
+ }
+
+ public Object nextElement() {
+ return get(m_iter.nextElement());
+ }
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryPropertyResolver.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryPropertyResolver.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryPropertyResolver.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositoryPropertyResolver.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,82 @@
+package org.apache.ace.client.repository.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.helper.PropertyResolver;
+import org.apache.ace.client.repository.object.TargetObject;
+import org.apache.ace.client.repository.object.FeatureObject;
+import org.apache.ace.client.repository.object.DistributionObject;
+
+/**
+ * This PropertyResolver first tries to resolve the key in the
+ * current repository object. If not found, it looks for the key
+ * in its children.
+ */
+public class RepositoryPropertyResolver implements PropertyResolver {
+
+ private final RepositoryObject m_repositoryObject;
+
+ public RepositoryPropertyResolver(RepositoryObject repositoryObject) {
+ m_repositoryObject = repositoryObject;
+ }
+
+ public String get(String key) {
+ return get(key, m_repositoryObject);
+ }
+
+ private String get(String key, RepositoryObject ro) {
+ // Is it in this object?
+ String result = findKeyInObject(ro, key);
+ if (result != null) {
+ return result;
+ }
+
+ // Is it in one of the children?
+ List<? extends RepositoryObject> children = getChildren(ro);
+ for (RepositoryObject child : children) {
+ result = findKeyInObject(child, key);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ // Not found yet? then continue to the next level recursively.
+ for (RepositoryObject child : children) {
+ result = get(key, child);
+ if (result != null) {
+ return result;
+ }
+ }
+ return result;
+ }
+
+ protected List<? extends RepositoryObject> getChildren() {
+ return getChildren(m_repositoryObject);
+ }
+
+ protected List<? extends RepositoryObject> getChildren(RepositoryObject ob) {
+ if (ob instanceof TargetObject) {
+ return ((TargetObject) ob).getDistributions();
+ }
+ else if (ob instanceof DistributionObject) {
+ return ((DistributionObject) ob).getFeatures();
+ }
+ else if (ob instanceof FeatureObject) {
+ return ((FeatureObject) ob).getArtifacts();
+ }
+ return new ArrayList<RepositoryObject>();
+ }
+
+ private String findKeyInObject(RepositoryObject ro, String key) {
+ String result;
+ if ((result = ro.getAttribute(key)) != null) {
+ return result;
+ }
+ if ((result = ro.getTag(key)) != null) {
+ return result;
+ }
+ return null;
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySerializer.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySerializer.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySerializer.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySerializer.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,133 @@
+/*
+ * 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.ace.client.repository.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+/**
+ * Helper class that takes a RepositorySet<br>
+ * TODO We might move out xstream at some time in the future; before that
+ * time, it could be a smart idea to wrap xstream's writer in a delegate
+ * object, so this will not require changes to the repositories
+ * and objects.
+ */
+class RepositorySerializer implements Converter {
+ @SuppressWarnings("unchecked")
+ private final Map<String, ObjectRepositoryImpl> m_tagToRepo = new HashMap<String, ObjectRepositoryImpl>();
+
+ private final RepositorySet m_set;
+
+ private final XStream m_stream;
+
+ @SuppressWarnings("unchecked")
+ RepositorySerializer(RepositorySet set) {
+ m_set = set;
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ m_tagToRepo.put(repo.getXmlNode(), repo);
+ }
+ m_stream = new XStream();
+ m_stream.alias("repository", getClass());
+ m_stream.registerConverter(this);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void marshal(Object target, HierarchicalStreamWriter writer, MarshallingContext context) {
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ repo.marshal(writer);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+ while(reader.hasMoreChildren()) {
+ reader.moveDown();
+ String nodeName = reader.getNodeName();
+ ObjectRepositoryImpl o = m_tagToRepo.get(nodeName);
+ o.unmarshal(reader);
+ reader.moveUp();
+ }
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean canConvert(Class target) {
+ return target == getClass();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void toXML(OutputStream out) {
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ repo.setBusy(true);
+ }
+ try {
+ m_stream.toXML(this, out);
+ }
+ finally {
+ // Ensure all busy flags are reset at all times...
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ repo.setBusy(false);
+ }
+ }
+ }
+
+ /**
+ * Reads the repositories with which this RepositoryRoot had been initialized with from the
+ * given XML file.
+ * @param in The input stream.
+ */
+ @SuppressWarnings("unchecked")
+ public void fromXML(InputStream in) {
+ // The repositories get cleared, since a user *could* add stuff before
+ // checking out.
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ repo.setBusy(true);
+ repo.removeAll();
+ }
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ if (in.available() > 0) {
+ m_stream.fromXML(in, this);
+ }
+ }
+ catch (IOException e) {
+ // This means the stream has been closed before we got it.
+ // Since the repository is now in a consistent state, just move on.
+ e.printStackTrace();
+ }
+ finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ // Ensure all busy flags are reset at all times...
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ repo.setBusy(false);
+ }
+ }
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySet.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySet.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySet.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/RepositorySet.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,369 @@
+/*
+ * 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.ace.client.repository.impl;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.ace.client.repository.ObjectRepository;
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.RepositoryObject.WorkingState;
+import org.apache.ace.client.repository.SessionFactory;
+import org.apache.ace.repository.ext.CachedRepository;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
+import org.osgi.service.log.LogService;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+import org.osgi.service.useradmin.User;
+
+/**
+ * This class encapsulates a set of <code>ObjectRepositoryImpl</code>s, and manages
+ * auxiliary information and functionality that is linked to that set.
+ */
+class RepositorySet {
+ private final static String PREFS_LOCAL_WORKING_STATE = "workingState";
+ private final static String PREFS_LOCAL_WORKING_STATE_VALUE = "workingStateValue";
+ private final static String PREFS_LOCAL_FILE_VERSION = "version";
+
+ private final User m_user;
+ private final Preferences m_prefs;
+ @SuppressWarnings("unchecked")
+ private final ObjectRepositoryImpl[] m_repos;
+ private final CachedRepository m_repository;
+ private final String m_name;
+ private final boolean m_writeAccess;
+ private final ConcurrentMap<RepositoryObject, WorkingState> m_workingState;
+ private final ChangeNotifier m_notifier;
+ private final LogService m_log;
+
+ private volatile ServiceRegistration m_modifiedHandler;
+
+ /* ********
+ * Basics
+ * ********/
+
+ @SuppressWarnings("unchecked")
+ /**
+ * Creates a new <code>RepositorySet</code>. Notes:
+ * <ul>
+ * <li>When storing association repositories in <code>repos</code>, it is wise to
+ * put these in last. This has to do with the method of deserialization, which assumes
+ * that endpoints of an association are available at the time of deserialization.</li>
+ * </ul>
+ */
+ RepositorySet(ChangeNotifier notifier, LogService log, User user, Preferences prefs, ObjectRepositoryImpl[] repos, CachedRepository repository, String name, boolean writeAccess) {
+ m_workingState = new ConcurrentHashMap<RepositoryObject, WorkingState>();
+ m_notifier = notifier;
+ m_log = log;
+ m_user = user;
+ m_prefs = prefs;
+ m_repos = repos;
+ m_repository = repository;
+ m_name = name;
+ m_writeAccess = writeAccess;
+ }
+
+ void unregisterHandler() {
+ m_modifiedHandler.unregister();
+ m_modifiedHandler = null;
+ }
+
+ boolean writeAccess() {
+ return m_writeAccess;
+ }
+
+ boolean isModified() {
+ for (WorkingState workingState : m_workingState.values()) {
+ if (!WorkingState.Unchanged.equals(workingState)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ User getUser() {
+ return m_user;
+ }
+
+ @SuppressWarnings("unchecked")
+ ObjectRepositoryImpl[] getRepos() {
+ return m_repos;
+ }
+
+ String getName() {
+ return m_name;
+ }
+
+ /* ********
+ * Preferences
+ * ********/
+
+ void savePreferences() {
+ Preferences workingNode = m_prefs.node(PREFS_LOCAL_WORKING_STATE);
+ try {
+ workingNode.clear();
+ }
+ catch (BackingStoreException e) {
+ // Something went wrong clearing the node... Too bad, this means we
+ // cannot store the properties.
+ m_log.log(LogService.LOG_WARNING, "Could not store all preferences for " + workingNode.absolutePath());
+ e.printStackTrace();
+ }
+
+ for (Map.Entry<RepositoryObject, WorkingState> entry : m_workingState.entrySet()) {
+ workingNode.node(entry.getKey().getDefinition()).put(PREFS_LOCAL_WORKING_STATE_VALUE, entry.getValue().toString());
+ }
+
+ m_prefs.putLong(PREFS_LOCAL_FILE_VERSION, m_repository.getMostRecentVersion());
+ }
+
+ /**
+ * Only call this after the repository has been deserialized.
+ */
+ void loadPreferences() {
+ Preferences workingNode = m_prefs.node(PREFS_LOCAL_WORKING_STATE);
+ Map<String, WorkingState> entries = new HashMap<String, WorkingState>();
+ // First, get all nodes and their workingstate.
+ try {
+ String defaultWorkingState = WorkingState.Unchanged.toString();
+
+ for (String node : workingNode.childrenNames()) {
+ String state = workingNode.node(node).get(PREFS_LOCAL_WORKING_STATE_VALUE, defaultWorkingState);
+ entries.put(node, WorkingState.valueOf(state));
+ }
+ }
+ catch (BackingStoreException e) {
+ // Something went wrong reading from the store, just work with whatever we have in the map.
+ m_log.log(LogService.LOG_WARNING, "Could not load all preferences for " + workingNode.absolutePath());
+ e.printStackTrace();
+ }
+ // Then, go through all objects and check whether they match a definition we know.
+ // This prevents calling getDefinition more than once per object.
+ for (ObjectRepository<RepositoryObject> repo : m_repos) {
+ for (RepositoryObject o : repo.get()) {
+ WorkingState state = entries.get(o.getDefinition());
+ if (state != null) {
+ m_workingState.put(o, state);
+ }
+ }
+ }
+ }
+
+ /* ********
+ * Persistence
+ * ********/
+
+ boolean readLocal() throws IOException {
+ InputStream input = m_repository.getLocal(false /* fail */);
+ if (input.available() > 0) {
+ read(input);
+ return true;
+ }
+ else {
+ closeSafely(input);
+ return false;
+ }
+ }
+
+ void read(InputStream input) {
+ new RepositorySerializer(this).fromXML(input);
+ closeSafely(input);
+ }
+
+ void writeLocal() throws IOException {
+ final PipedInputStream input = new PipedInputStream();
+ final PipedOutputStream output = new PipedOutputStream(input);
+ new Thread(new Runnable() {
+ public void run() {
+ new RepositorySerializer(RepositorySet.this).toXML(output);
+ try {
+ output.flush();
+ output.close();
+ }
+ catch (IOException e) {
+ // There is no way to tell this to the user, but the other side will
+ // notice that the pipe is broken.
+ }
+ }
+ }, "write(" + m_name + ")").start();
+ m_repository.writeLocal(input);
+ input.close();
+ }
+
+ void commit() throws IOException {
+ if (!isCurrent()) {
+ throw new IllegalStateException("When committing the " + m_name + ", it should be current.");
+ }
+ writeLocal();
+ if (m_writeAccess) {
+ m_repository.commit();
+ }
+ resetModified(false);
+ }
+
+ void checkout() throws IOException {
+ read(m_repository.checkout(false));
+ resetModified(true);
+ }
+
+ void revert() throws IOException {
+ m_repository.revert();
+ read(m_repository.getLocal(false));
+ resetModified(false);
+ }
+
+ boolean isCurrent() throws IOException {
+ return m_repository.isCurrent();
+ }
+
+ @SuppressWarnings("unchecked")
+ void clearRepositories() {
+ for (ObjectRepositoryImpl repo : getRepos()) {
+ repo.setBusy(true);
+ }
+
+ try {
+ for (ObjectRepositoryImpl repo : getRepos()) {
+ repo.removeAll();
+ }
+ }
+ finally {
+ // Ensure all busy flags are reset at all times...
+ for (ObjectRepositoryImpl repo : getRepos()) {
+ repo.setBusy(false);
+ }
+ }
+ }
+
+ void deleteLocal() {
+ try {
+ m_repository.deleteLocal();
+ }
+ catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /* ********
+ * Event handling
+ * ********/
+
+ void registerHandler(BundleContext context, String sessionID, String... topics) {
+ if (m_modifiedHandler != null) {
+ throw new IllegalStateException("A handler is already registered; only one can be used at a time.");
+ }
+ Dictionary topic = new Hashtable();
+ topic.put(EventConstants.EVENT_TOPIC, topics);
+ topic.put(EventConstants.EVENT_FILTER, "(" + SessionFactory.SERVICE_SID + "=" + sessionID + ")");
+ m_modifiedHandler = context.registerService(EventHandler.class.getName(), new ModifiedHandler(), topic);
+ }
+
+ WorkingState getWorkingState(RepositoryObject object) {
+ return m_workingState.get(object);
+ }
+
+ int getNumberWithWorkingState(Class<? extends RepositoryObject> clazz, WorkingState state) {
+ int result = 0;
+ for (Map.Entry<RepositoryObject, WorkingState> entry : m_workingState.entrySet()) {
+ if (clazz.isInstance(entry.getKey()) && state.equals(entry.getValue())) {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ private void resetModified(boolean fill) {
+ m_workingState.clear();
+ if (fill) {
+ for (ObjectRepository<? extends RepositoryObject> repo : m_repos) {
+ for (RepositoryObject object : repo.get()) {
+ m_workingState.put(object, WorkingState.Unchanged);
+ }
+ }
+ }
+ m_notifier.notifyChanged(RepositoryAdmin.TOPIC_STATUSCHANGED_SUFFIX, null);
+ }
+
+ private void closeSafely(Closeable resource) {
+ if (resource != null) {
+ try {
+ resource.close();
+ }
+ catch (IOException e) {
+ // Ignored; not much we can do about this...
+ m_log.log(LogService.LOG_DEBUG, "Closing resource failed!", e);
+ }
+ }
+ }
+
+ final class ModifiedHandler implements EventHandler {
+
+ public void handleEvent(Event event) {
+ /*
+ * NOTE: if recalculating the state for every event turns out to be
+ * too expensive, we can cache the 'modified' state and not recalculate
+ * it every time.
+ */
+
+ boolean wasModified = isModified();
+
+ RepositoryObject object = (RepositoryObject) event.getProperty(RepositoryObject.EVENT_ENTITY);
+ String topic = event.getTopic();
+
+ WorkingState newState = WorkingState.Unchanged;
+ if (topic.endsWith("/ADDED")) {
+ newState = WorkingState.New;
+ }
+ else if (topic.endsWith("/CHANGED")) {
+ newState = WorkingState.Changed;
+ }
+ else if (topic.endsWith("/REMOVED")) {
+ newState = WorkingState.Removed;
+ }
+
+ if (!newState.equals(m_workingState.get(object))) {
+ m_workingState.put(object, newState);
+
+ Properties props = new Properties();
+ props.put(RepositoryObject.EVENT_ENTITY, object);
+ m_notifier.notifyChanged(RepositoryAdmin.TOPIC_STATUSCHANGED_SUFFIX, props);
+ }
+
+ if (!wasModified) {
+ m_notifier.notifyChanged(RepositoryAdmin.TOPIC_STATUSCHANGED_SUFFIX, null);
+ }
+ }
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetObjectImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetObjectImpl.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetObjectImpl.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetObjectImpl.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,83 @@
+/*
+ * 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.ace.client.repository.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ace.client.repository.object.TargetObject;
+import org.apache.ace.client.repository.object.Distribution2TargetAssociation;
+import org.apache.ace.client.repository.object.DistributionObject;
+
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+
+/**
+ * Implementation class for the TargetObject. For 'what it does', see TargetObject,
+ * for 'how it works', see RepositoryObjectImpl.
+ */
+public class TargetObjectImpl extends RepositoryObjectImpl<TargetObject> implements TargetObject {
+ private final static String XML_NODE = "target";
+
+ TargetObjectImpl(Map<String, String> attributes, ChangeNotifier notifier) {
+ super(checkAttributes(attributes, KEY_ID), notifier, XML_NODE);
+ }
+
+ TargetObjectImpl(Map<String, String> attributes, Map<String, String> tags, ChangeNotifier notifier) {
+ super(checkAttributes(attributes, KEY_ID), tags, notifier, XML_NODE);
+ }
+
+ TargetObjectImpl(HierarchicalStreamReader reader, ChangeNotifier notifier) {
+ super(reader, notifier, XML_NODE);
+ if(getAttribute(KEY_AUTO_APPROVE) == null) {
+ addAttribute(KEY_AUTO_APPROVE, String.valueOf(false));
+ }
+ }
+
+ public List<DistributionObject> getDistributions() {
+ return getAssociations(DistributionObject.class);
+ }
+
+ public String getID() {
+ return getAttribute(KEY_ID);
+ }
+
+ public List<Distribution2TargetAssociation> getAssociationsWith(DistributionObject distribution) {
+ return getAssociationsWith(distribution, DistributionObject.class, Distribution2TargetAssociation.class);
+ }
+
+ private static String[] DEFINING_KEYS = new String[] {KEY_ID};
+ @Override
+ String[] getDefiningKeys() {
+ return DEFINING_KEYS;
+ }
+
+ public boolean getAutoApprove() {
+ String value = getAttribute(KEY_AUTO_APPROVE);
+ if (value == null) {
+ return false;
+ }
+ else {
+ return Boolean.parseBoolean(value);
+ }
+ }
+
+ public void setAutoApprove(boolean approve) {
+ addAttribute(KEY_AUTO_APPROVE, String.valueOf(approve));
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetPropertyResolver.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetPropertyResolver.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetPropertyResolver.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetPropertyResolver.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,84 @@
+/*
+ * 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.ace.client.repository.impl;
+
+import java.util.*;
+
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.helper.PropertyResolver;
+import org.apache.ace.client.repository.object.TargetObject;
+
+/**
+ * Top-level property resolver, also able to return collections
+ * of distributions, features and artifacts linked to this target
+ * repository object.
+ */
+public class TargetPropertyResolver extends RepositoryPropertyResolver {
+
+ public TargetPropertyResolver(TargetObject to) {
+ super(to);
+ }
+
+ public Collection<PropertyResolver> getDistributions() {
+ List<PropertyResolver> list = new ArrayList<PropertyResolver>();
+
+ List<RepositoryObject> distributions = (List<RepositoryObject>)getChildren();
+
+ for (RepositoryObject repo : distributions) {
+ list.add(new RepositoryPropertyResolver(repo));
+ }
+
+ return list;
+ }
+
+ public Collection<PropertyResolver> getFeatures() {
+ List<PropertyResolver> list = new ArrayList<PropertyResolver>();
+
+ Set<RepositoryObject> features = new HashSet<RepositoryObject>();
+
+ for (RepositoryObject repositoryObject : getChildren()) {
+ features.addAll(getChildren(repositoryObject));
+ }
+
+ for (RepositoryObject repo : features) {
+ list.add(new RepositoryPropertyResolver(repo));
+ }
+ return list;
+ }
+
+ public Collection<PropertyResolver> getArtifacts() {
+ List<PropertyResolver> list = new ArrayList<PropertyResolver>();
+
+ Set<RepositoryObject> artifacts = new HashSet<RepositoryObject>();
+ Set<RepositoryObject> features = new HashSet<RepositoryObject>();
+
+ for (RepositoryObject repositoryObject : getChildren()) {
+ features.addAll(getChildren(repositoryObject));
+ }
+
+ for (RepositoryObject repositoryObject : features) {
+ artifacts.addAll(getChildren(repositoryObject));
+ }
+
+ for (RepositoryObject repo : artifacts) {
+ list.add(new RepositoryPropertyResolver(repo));
+ }
+ return list;
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetRepositoryImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetRepositoryImpl.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetRepositoryImpl.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/impl/TargetRepositoryImpl.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,53 @@
+/*
+ * 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.ace.client.repository.impl;
+
+import java.util.Map;
+
+import org.apache.ace.client.repository.object.TargetObject;
+import org.apache.ace.client.repository.repository.TargetRepository;
+
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+
+/**
+ * Implementation class for the TargetRepository. For 'what it does', see TargetRepository,
+ * for 'how it works', see ObjectRepositoryImpl.
+ */
+public class TargetRepositoryImpl extends ObjectRepositoryImpl<TargetObjectImpl, TargetObject> implements TargetRepository {
+ private final static String XML_NODE = "targets";
+
+ public TargetRepositoryImpl(ChangeNotifier notifier) {
+ super(notifier, XML_NODE);
+ }
+
+ @Override
+ TargetObjectImpl createNewInhabitant(Map<String, String> attributes, Map<String, String> tags) {
+ return new TargetObjectImpl(attributes, tags, this);
+ }
+
+ @Override
+ TargetObjectImpl createNewInhabitant(Map<String, String> attributes) {
+ return new TargetObjectImpl(attributes, this);
+ }
+
+ @Override
+ TargetObjectImpl createNewInhabitant(HierarchicalStreamReader reader) {
+ return new TargetObjectImpl(reader, this);
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Artifact2FeatureAssociation.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Artifact2FeatureAssociation.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Artifact2FeatureAssociation.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Artifact2FeatureAssociation.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,33 @@
+/*
+ * 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.ace.client.repository.object;
+
+import org.apache.ace.client.repository.Association;
+
+/**
+ * Interface to a Artifact2FeatureAssociation. Most functionality is defined by the generic Association.
+ */
+public interface Artifact2FeatureAssociation extends Association<ArtifactObject, FeatureObject> {
+ public static final String TOPIC_ENTITY_ROOT = Artifact2FeatureAssociation.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/ArtifactObject.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,113 @@
+/*
+ * 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.ace.client.repository.object;
+
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryObject;
+
+/**
+ * Interface to an ArtifactObject. The basic functionality is defined by RepositoryObject, but extended for
+ * artifact-specific information.
+ */
+public interface ArtifactObject extends RepositoryObject {
+ /**
+ * Key to be used in the <code>ArtifactObject</code>'s attributes.
+ * Indicates the location of the persistent storage of the artifact.
+ */
+ public static final String KEY_URL = "url";
+ /**
+ * Attribute key, stating the unique name for this resource. Different versions of the same logical resource
+ * can share the same Id.
+ */
+ public static final String KEY_RESOURCE_ID = "resourceId";
+ /**
+ * Key to be used in the <code>ArtifactObject</code>'s attributes.
+ * Indicates the PID of the resource processor that should be used to process this artifact.
+ * For a bundle, it is empty.
+ */
+ public static final String KEY_PROCESSOR_PID = "processorPid";
+ /**
+ * Key to be used in the <code>ArtifactObject</code>'s attributes.
+ * Indicates the mimetype of this artifact. For artifacts which do not
+ * have an adequately discriminating mimetype, it can be extended with
+ * something non-standard.
+ */
+ public static final String KEY_MIMETYPE = "mimetype";
+ /**
+ * Key to be used in the <code>ArtifactObject</code>'s attributes.
+ * Holds a human-readable name for this artifact.
+ */
+ public static final String KEY_ARTIFACT_NAME = "artifactName";
+ /**
+ * Key to be used in the <code>ArtifactObject</code>'s attributes.
+ * Holds a human-readable description for this artifact.
+ */
+ public static final String KEY_ARTIFACT_DESCRIPTION = "artifactDescription";
+
+ public static final String TOPIC_ENTITY_ROOT = ArtifactObject.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+
+ /**
+ * Returns all <code>GroupObject</code>s this object is associated with. If there
+ * are none, an empty list will be returned.
+ */
+ public List<FeatureObject> getFeatures();
+ /**
+ * Returns all associations this artifact has with a given group.
+ */
+ public List<Artifact2FeatureAssociation> getAssociationsWith(FeatureObject group);
+
+ /**
+ * Returns the mimetype of this artifact.
+ */
+ public String getMimetype();
+ /**
+ * Returns the PID of the resource processor of this artifact.
+ */
+ public String getProcessorPID();
+ /**
+ * Sets the PID of the resource processor of this artifact.
+ */
+ public void setProcessorPID(String processorPID);
+ /**
+ * Returns the URL to this artifact.
+ */
+ public String getURL();
+ /**
+ * Returns a ResourceId, if that has been customized.
+ */
+ public String getResourceId();
+ /**
+ * Return a descriptive name for this object. May return <code>null</code>.
+ */
+ public String getName();
+ /**
+ * Returns a description for this object. May return <code>null</code>.
+ */
+ public String getDescription();
+ /**
+ * Sets a description for this artifact.
+ */
+ public void setDescription(String value);
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentArtifact.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,69 @@
+/*
+ * 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.ace.client.repository.object;
+
+/**
+ * Interface to a deployment artifact, which is used to gather information about
+ * the deployment of a single artifact.
+ */
+public interface DeploymentArtifact {
+
+ /**
+ * Key, intended to be used for artifacts which are bundles and will publish
+ * a resource processor (see OSGi compendium section 114.10).
+ */
+ public static final String DIRECTIVE_ISCUSTOMIZER = "DeploymentPackage-Customizer";
+
+ /**
+ * Key, intended to be used for resources which require a resource processor
+ * (see OSGi compendium section 114.10).
+ */
+ public static final String DIRECTIVE_KEY_PROCESSORID = "Resource-Processor";
+
+ /**
+ * Key, intended to be used for artifacts which have a resourceID that's different
+ * from their generated name (based on URL).
+ */
+ public static final String DIRECTIVE_KEY_RESOURCE_ID = "Resource-ID";
+
+ /**
+ * Key, intended to be used for matching processed (see ArtifactPreprocessor) to their
+ * 'original' one.
+ */
+ public static final String DIRECTIVE_KEY_BASEURL = "Base-Url";
+
+ public static final String REPOSITORY_PATH = "ACE-RepositoryPath";
+
+ /**
+ * @return the URL for this deployment artifact.
+ */
+ public String getUrl();
+
+ /**
+ * @param key A key String, such as the <code>DIRECTIVE_</code> constants in
+ * <code>DeploymentArtifact</code>.
+ * @return the value for the given directive key, or <code>null</code> if not found.
+ */
+ public String getDirective(String key);
+
+ /**
+ * @return an array of all keys that are used in this object, to be used in <code>getDirective</code>.
+ */
+ public String[] getKeys();
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentVersionObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentVersionObject.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentVersionObject.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DeploymentVersionObject.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,58 @@
+/*
+ * 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.ace.client.repository.object;
+
+import org.apache.ace.client.repository.RepositoryObject;
+
+/**
+ * The interface to a DeploymentVersion. The basic functionality is defined
+ * by RepositoryObject, but extended for deployment version-specific information.
+ *
+ * DeploymentVersions need some additional information about the artifacts they
+ * are associated with; see DeploymentArtifact.
+ */
+public interface DeploymentVersionObject extends RepositoryObject {
+
+ public static final String KEY_TARGETID = "targetID";
+ public static final String KEY_VERSION = "version";
+
+ public static final String TOPIC_ENTITY_ROOT = DeploymentVersionObject.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+
+ /**
+ * Gets the target which is related to this version.
+ */
+ public String getTargetID();
+
+ /**
+ * Gets the version number of this deployment version.
+ */
+ public String getVersion();
+
+ /**
+ * @return an array of all deployment artifacts that will be part of this deployment version.
+ * The order of the artifacts in the array is equal to the order they should appear in a
+ * deployment package.
+ */
+ public DeploymentArtifact[] getDeploymentArtifacts();
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Distribution2TargetAssociation.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Distribution2TargetAssociation.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Distribution2TargetAssociation.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Distribution2TargetAssociation.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,33 @@
+/*
+ * 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.ace.client.repository.object;
+
+import org.apache.ace.client.repository.Association;
+
+/**
+ * Interface to a Distribution2TargetAssociation. Most functionality is defined by the generic Association.
+ */
+public interface Distribution2TargetAssociation extends Association<DistributionObject, TargetObject> {
+ public static final String TOPIC_ENTITY_ROOT = Distribution2TargetAssociation.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DistributionObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DistributionObject.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DistributionObject.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/DistributionObject.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,81 @@
+/*
+ * 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.ace.client.repository.object;
+
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryObject;
+
+/**
+ * Interface to a DistributionObject. The basic functionality is defined by RepositoryObject, but extended for
+ * distribution-specific information.
+ */
+public interface DistributionObject extends RepositoryObject {
+ public static final String TOPIC_ENTITY_ROOT = DistributionObject.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+
+ public static final String KEY_DESCRIPTION = "description";
+ public static final String KEY_NAME = "name";
+
+ /**
+ * Returns all <code>FeatureObject</code>s this object is associated with. If there
+ * are none, an empty list will be returned.
+ */
+ public List<FeatureObject> getFeatures();
+
+ /**
+ * Returns all <code>TargetObject</code>s this object is associated with. If there
+ * are none, an empty list will be returned.
+ */
+ public List<TargetObject> getTargets();
+
+ /**
+ * Returns all associations this distribution has with a given feature.
+ */
+ public List<Feature2DistributionAssociation> getAssociationsWith(FeatureObject feature);
+
+ /**
+ * Returns all associations this distribution has with a given target.
+ */
+ public List<Distribution2TargetAssociation> getAssociationsWith(TargetObject target);
+
+ /**
+ * Returns the name of this distribution.
+ */
+ public String getName();
+
+ /**
+ * Sets the name of this distribution.
+ */
+ public void setName(String name);
+
+ /**
+ * Returns the description of this distribution.
+ */
+ public String getDescription();
+
+ /**
+ * Sets the description of this distribution.
+ */
+ public void setDescription(String description);
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Feature2DistributionAssociation.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Feature2DistributionAssociation.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Feature2DistributionAssociation.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/Feature2DistributionAssociation.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,33 @@
+/*
+ * 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.ace.client.repository.object;
+
+import org.apache.ace.client.repository.Association;
+
+/**
+ * Interface to a Feature2DistributionAssociation. Most functionality is defined by the generic Association.
+ */
+public interface Feature2DistributionAssociation extends Association<FeatureObject, DistributionObject> {
+ public static final String TOPIC_ENTITY_ROOT = Feature2DistributionAssociation.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/FeatureObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/FeatureObject.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/FeatureObject.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/FeatureObject.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,81 @@
+/*
+ * 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.ace.client.repository.object;
+
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryObject;
+
+/**
+ * Interface to a FeatureObject. The basic functionality is defined by RepositoryObject, but extended for
+ * feature-specific information.
+ */
+public interface FeatureObject extends RepositoryObject {
+ public static final String KEY_DESCRIPTION = "description";
+ public static final String KEY_NAME = "name";
+
+ public static final String TOPIC_ENTITY_ROOT = FeatureObject.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+
+ /**
+ * Returns all <code>ArtifactObject</code>s this object is associated with. If there
+ * are none, an empty list will be returned.
+ */
+ public List<ArtifactObject> getArtifacts();
+
+ /**
+ * Returns all <code>DistributionObject</code>s this object is associated with. If there
+ * are none, an empty list will be returned.
+ */
+ public List<DistributionObject> getDistributions();
+
+ /**
+ * Returns all associations this feature has with a given artifact.
+ */
+ public List<Artifact2FeatureAssociation> getAssociationsWith(ArtifactObject artifact);
+
+ /**
+ * Returns all associations this feature has with a given distribution.
+ */
+ public List<Feature2DistributionAssociation> getAssociationsWith(DistributionObject distribution);
+
+ /**
+ * Returns the name of this feature.
+ */
+ public String getName();
+
+ /**
+ * Sets the name of this feature.
+ */
+ public void setName(String name);
+
+ /**
+ * Returns the description of this feature.
+ */
+ public String getDescription();
+
+ /**
+ * Sets the description of this feature.
+ */
+ public void setDescription(String description);
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/TargetObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/TargetObject.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/TargetObject.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/TargetObject.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,60 @@
+/*
+ * 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.ace.client.repository.object;
+
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryObject;
+
+public interface TargetObject extends RepositoryObject {
+ public static final String KEY_ID = "id";
+ public static final String KEY_AUTO_APPROVE = "autoapprove";
+
+ public static final String TOPIC_ENTITY_ROOT = TargetObject.class.getSimpleName() + "/";
+
+ public static final String TOPIC_ADDED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ADDED_SUFFIX;
+ public static final String TOPIC_REMOVED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_REMOVED_SUFFIX;
+ public static final String TOPIC_CHANGED = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_CHANGED_SUFFIX;
+ public static final String TOPIC_ALL = PUBLIC_TOPIC_ROOT + TOPIC_ENTITY_ROOT + TOPIC_ALL_SUFFIX;
+
+ /**
+ * Returns all <code>DistributionObject</code>s this object is associated with. If there
+ * are none, an empty list will be returned.
+ */
+ public List<DistributionObject> getDistributions();
+ /**
+ * Returns all associations this target has with a given distribution.
+ */
+ public List<Distribution2TargetAssociation> getAssociationsWith(DistributionObject distribution);
+
+ /**
+ * Gets the ID of this TargetObject.
+ */
+ public String getID();
+
+ /**
+ * Enable or disable automatic approval.
+ */
+ public void setAutoApprove(boolean approve);
+
+ /**
+ * Get the auto approval value of this target.
+ */
+ public boolean getAutoApprove();
+}
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/packageinfo?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/packageinfo (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/object/packageinfo Tue Apr 2 14:53:33 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/packageinfo
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/packageinfo?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/packageinfo (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/packageinfo Tue Apr 2 14:53:33 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
Added: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/Artifact2FeatureAssociationRepository.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/Artifact2FeatureAssociationRepository.java?rev=1463576&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/Artifact2FeatureAssociationRepository.java (added)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/repository/Artifact2FeatureAssociationRepository.java Tue Apr 2 14:53:33 2013
@@ -0,0 +1,30 @@
+/*
+ * 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.ace.client.repository.repository;
+
+import org.apache.ace.client.repository.AssociationRepository;
+import org.apache.ace.client.repository.object.Artifact2FeatureAssociation;
+import org.apache.ace.client.repository.object.ArtifactObject;
+import org.apache.ace.client.repository.object.FeatureObject;
+
+/**
+ * Interface to a Artifact2FeatureAssociationRepository. The functionality is defined by the generic AssociationRepository.
+ */
+public interface Artifact2FeatureAssociationRepository extends AssociationRepository<ArtifactObject, FeatureObject, Artifact2FeatureAssociation> {
+}