Fix checkstyle issues to enforce it
[controller.git] / opendaylight / config / config-persister-feature-adapter / src / main / java / org / opendaylight / controller / configpusherfeature / internal / FeatureConfigSnapshotHolder.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.configpusherfeature.internal;
9
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;
14
15 import java.io.File;
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;
21
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;
29
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;
34
35 /*
36  * A ConfigSnapshotHolder that can track all the additional information
37  * relavent to the fact we are getting these from a Feature.
38  *
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
42  */
43 public class FeatureConfigSnapshotHolder implements ConfigSnapshotHolder {
44     private ConfigSnapshot unmarshalled = null;
45     private ConfigFileInfo fileInfo = null;
46     private List<Feature> featureChain = new ArrayList<>();
47
48     /*
49      * @param holder - FeatureConfigSnapshotHolder that we
50      * @param feature - new
51      */
52     public FeatureConfigSnapshotHolder(final FeatureConfigSnapshotHolder holder,
53                                        final Feature feature) throws JAXBException, XMLStreamException {
54         this(holder.fileInfo, holder.getFeature());
55         this.featureChain.add(feature);
56     }
57
58     /*
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
63      */
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);
77
78         XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(new File(fileInfo.getFinalname())));
79         unmarshalled = (ConfigSnapshot) um.unmarshal(xsr);
80     }
81
82     /*
83      * (non-Javadoc)
84      * @see java.lang.Object#hashCode()
85      *
86      * We really care most about the underlying ConfigShapshot, so compute hashcode on that
87      */
88     @Override
89     public int hashCode() {
90         final int prime = 31;
91         int result = 1;
92         result = prime * result + ((unmarshalled != null && unmarshalled.getConfigSnapshot() == null) ? 0 :
93                 unmarshalled.getConfigSnapshot().hashCode());
94         return result;
95     }
96
97     /*
98      * (non-Javadoc)
99      * @see java.lang.Object#equals(java.lang.Object)
100      * *
101      * We really care most about the underlying ConfigShapshot, so compute equality on that
102      */
103     @Override
104     public boolean equals(final Object obj) {
105         if (this == obj) {
106             return true;
107         }
108         if (obj == null) {
109             return false;
110         }
111         if (getClass() != obj.getClass()) {
112             return false;
113         }
114         FeatureConfigSnapshotHolder fcsh = (FeatureConfigSnapshotHolder) obj;
115         if (this.unmarshalled.getConfigSnapshot().equals(fcsh.unmarshalled.getConfigSnapshot())) {
116             return true;
117         }
118         return false;
119     }
120
121     @Override
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())
126                 .append(")");
127         return stringBuilder.toString();
128     }
129
130     @Override
131     public String getConfigSnapshot() {
132         return unmarshalled.getConfigSnapshot();
133     }
134
135     @Override
136     public SortedSet<String> getCapabilities() {
137         return unmarshalled.getCapabilities();
138     }
139
140     public ConfigFileInfo getFileInfo() {
141         return fileInfo;
142     }
143
144     /*
145      * @returns The original feature to which the ConfigFileInfo was attached
146      * Example:
147      * A -> B -> C, ConfigFileInfo Foo is attached to C.
148      * feature:install A
149      * thus C is the 'Feature' Foo was attached.
150      */
151     public Feature getFeature() {
152         return featureChain.get(0);
153     }
154
155     /*
156      * @return The dependency chain of the features that caused the ConfigFileInfo to be pushed in reverse order.
157      * Example:
158      * A -> B -> C, ConfigFileInfo Foo is attached to C.
159      * The returned list is
160      * [C,B,A]
161      */
162     public ImmutableList<Feature> getFeatureChain() {
163         return ImmutableList.copyOf(Lists.reverse(featureChain));
164     }
165
166     /*
167      * @return The feature the installation of which was the root cause
168      * of this pushing of the ConfigFileInfo.
169      * Example:
170      * A -> B -> C, ConfigFileInfo Foo is attached to C.
171      * feature:install A
172      * this A is the 'Cause' of the installation of Foo.
173      */
174     public Feature getCauseFeature() {
175         return Iterables.getLast(featureChain);
176     }
177 }