2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.configpusherfeature.internal;
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableList;
12 import com.google.common.collect.Iterables;
13 import com.google.common.collect.Lists;
16 import java.nio.file.Path;
17 import java.nio.file.Paths;
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.SortedSet;
22 import javax.xml.bind.JAXBContext;
23 import javax.xml.bind.JAXBException;
24 import javax.xml.bind.Unmarshaller;
25 import javax.xml.stream.XMLInputFactory;
26 import javax.xml.stream.XMLStreamException;
27 import javax.xml.stream.XMLStreamReader;
28 import javax.xml.transform.stream.StreamSource;
30 import org.apache.karaf.features.ConfigFileInfo;
31 import org.apache.karaf.features.Feature;
32 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
33 import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
36 * A ConfigSnapshotHolder that can track all the additional information
37 * relavent to the fact we are getting these from a Feature.
39 * Includes tracking the 'featureChain' - an reverse ordered list of the dependency
40 * graph of features that caused us to push this FeatureConfigSnapshotHolder.
41 * So if A -> B -> C, then the feature chain would be C -> B -> A
43 public class FeatureConfigSnapshotHolder implements ConfigSnapshotHolder {
44 private ConfigSnapshot unmarshalled = null;
45 private ConfigFileInfo fileInfo = null;
46 private List<Feature> featureChain = new ArrayList<>();
49 * @param holder - FeatureConfigSnapshotHolder that we
50 * @param feature - new
52 public FeatureConfigSnapshotHolder(final FeatureConfigSnapshotHolder holder,
53 final Feature feature) throws JAXBException, XMLStreamException {
54 this(holder.fileInfo, holder.getFeature());
55 this.featureChain.add(feature);
59 * Create a FeatureConfigSnapshotHolder for a given ConfigFileInfo and record the associated
60 * feature we are creating it from.
61 * @param fileInfo - ConfigFileInfo to read into the ConfigSnapshot
62 * @param feature - Feature the ConfigFileInfo was attached to
64 public FeatureConfigSnapshotHolder(final ConfigFileInfo fileInfo,
65 final Feature feature) throws JAXBException, XMLStreamException {
66 Preconditions.checkNotNull(fileInfo);
67 Preconditions.checkNotNull(fileInfo.getFinalname());
68 Preconditions.checkNotNull(feature);
69 this.fileInfo = fileInfo;
70 this.featureChain.add(feature);
71 // TODO extract utility method for umarshalling config snapshots
72 JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
73 Unmarshaller um = jaxbContext.createUnmarshaller();
74 XMLInputFactory xif = XMLInputFactory.newFactory();
75 xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
76 xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
78 XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(new File(fileInfo.getFinalname())));
79 unmarshalled = (ConfigSnapshot) um.unmarshal(xsr);
84 * @see java.lang.Object#hashCode()
86 * We really care most about the underlying ConfigShapshot, so compute hashcode on that
89 public int hashCode() {
92 result = prime * result + ((unmarshalled != null && unmarshalled.getConfigSnapshot() == null) ? 0 :
93 unmarshalled.getConfigSnapshot().hashCode());
99 * @see java.lang.Object#equals(java.lang.Object)
101 * We really care most about the underlying ConfigShapshot, so compute equality on that
104 public boolean equals(final Object obj) {
111 if (getClass() != obj.getClass()) {
114 FeatureConfigSnapshotHolder fcsh = (FeatureConfigSnapshotHolder) obj;
115 if (this.unmarshalled.getConfigSnapshot().equals(fcsh.unmarshalled.getConfigSnapshot())) {
122 public String toString() {
123 StringBuilder stringBuilder = new StringBuilder();
124 Path path = Paths.get(fileInfo.getFinalname());
125 stringBuilder.append(path.getFileName()).append("(").append(getCauseFeature()).append(",").append(getFeature())
127 return stringBuilder.toString();
131 public String getConfigSnapshot() {
132 return unmarshalled.getConfigSnapshot();
136 public SortedSet<String> getCapabilities() {
137 return unmarshalled.getCapabilities();
140 public ConfigFileInfo getFileInfo() {
145 * @returns The original feature to which the ConfigFileInfo was attached
147 * A -> B -> C, ConfigFileInfo Foo is attached to C.
149 * thus C is the 'Feature' Foo was attached.
151 public Feature getFeature() {
152 return featureChain.get(0);
156 * @return The dependency chain of the features that caused the ConfigFileInfo to be pushed in reverse order.
158 * A -> B -> C, ConfigFileInfo Foo is attached to C.
159 * The returned list is
162 public ImmutableList<Feature> getFeatureChain() {
163 return ImmutableList.copyOf(Lists.reverse(featureChain));
167 * @return The feature the installation of which was the root cause
168 * of this pushing of the ConfigFileInfo.
170 * A -> B -> C, ConfigFileInfo Foo is attached to C.
172 * this A is the 'Cause' of the installation of Foo.
174 public Feature getCauseFeature() {
175 return Iterables.getLast(featureChain);