View Javadoc
1   /*
2     (C) Copyright IBM Corp. 2006, 2011
3   
4     THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
5     ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
6     CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
7   
8     You can obtain a current copy of the Eclipse Public License from
9     http://www.opensource.org/licenses/eclipse-1.0.php
10  
11    @author : Endre Bak, ebak@de.ibm.com
12   * 
13   * Flag       Date        Prog         Description
14   * -------------------------------------------------------------------------------
15   * 1565892    2006-10-09  ebak         Make SBLIM client JSR48 compliant
16   * 1660756    2007-02-22  ebak         Embedded object support
17   * 1737141    2007-06-18  ebak         Sync up with JSR48 evolution
18   * 1783288    2007-09-10  ebak         CIMClass.isAssociation() not working for retrieved classes.
19   * 1796339    2007-10-01  ebak         Serializable interface missing from internal componentry
20   * 1963102    2008-06-26  rgummada     NullPointerException when getting qualifiers
21   * 2003590    2008-06-30  blaschke-oss Change licensing from CPL to EPL
22   * 2524131    2009-01-21  raman_arora  Upgrade client to JDK 1.5 (Phase 1)
23   * 2531371    2009-02-10  raman_arora  Upgrade client to JDK 1.5 (Phase 2)
24   * 2620505    2009-02-24  rgummada     EmbeddedObject qualifier is missing from CIMClass
25   * 2797550    2009-06-01  raman_arora  JSR48 compliance - add Java Generics
26   * 2823494    2009-08-03  rgummada     Change Boolean constructor to static
27   * 2975885    2010-03-24  blaschke-oss TCK: CIMXXX.hasQualifierValue(null,null) returns true
28   * 3001680    2010-05-18  blaschke-oss CIMQualifierElementInterfaceImpl changes qualifiers
29   * 3023095    2010-07-01  blaschke-oss CIMQualifiedElementInterfaceImpl equals/hashCode issue
30   * 3154232    2011-01-13  blaschke-oss EmbeddedObject misspelled in javadoc
31   */
32  
33  package org.metricshub.wbem.sblim.cimclient.internal.cim;
34  
35  /*-
36   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
37   * WBEM Java Client
38   * ჻჻჻჻჻჻
39   * Copyright 2023 - 2025 MetricsHub
40   * ჻჻჻჻჻჻
41   * Licensed under the Apache License, Version 2.0 (the "License");
42   * you may not use this file except in compliance with the License.
43   * You may obtain a copy of the License at
44   *
45   *      http://www.apache.org/licenses/LICENSE-2.0
46   *
47   * Unless required by applicable law or agreed to in writing, software
48   * distributed under the License is distributed on an "AS IS" BASIS,
49   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50   * See the License for the specific language governing permissions and
51   * limitations under the License.
52   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
53   */
54  
55  import java.io.Serializable;
56  import java.util.ArrayList;
57  import java.util.Arrays;
58  import org.metricshub.wbem.javax.cim.CIMDataType;
59  import org.metricshub.wbem.javax.cim.CIMFlavor;
60  import org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface;
61  import org.metricshub.wbem.javax.cim.CIMQualifier;
62  
63  /**
64   * Class CIMQualifiedElementInterfaceImpl is responsible for implementing the
65   * functionality of javax.cim.CIMQualifiedElementInterface
66   */
67  public class CIMQualifiedElementInterfaceImpl implements CIMQualifiedElementInterface, Serializable {
68  	/**
69  	 * serialVersionUID
70  	 */
71  	private static final long serialVersionUID = 4533301297060752510L;
72  
73  	private CIMQualifier<?>[] iQualis;
74  
75  	private CIMQualifier<?>[] iLocalOnlyQualis;
76  
77  	private boolean iEmbeddedObject;
78  
79  	private static final CIMQualifier<Boolean> KEY = new CIMQualifier<Boolean>(
80  		"Key",
81  		CIMDataType.BOOLEAN_T,
82  		Boolean.TRUE,
83  		CIMFlavor.DISABLEOVERRIDE
84  	);
85  
86  	private static final CIMQualifier<Boolean> ASSOCIATION = new CIMQualifier<Boolean>(
87  		"Association",
88  		CIMDataType.BOOLEAN_T,
89  		Boolean.TRUE,
90  		CIMFlavor.DISABLEOVERRIDE
91  	);
92  
93  	private static final CIMQualifier<?>[] EMPTY_QA = new CIMQualifier[0];
94  
95  	/**
96  	 * Ctor. This constructor doesn't modify the passed qualifier list.
97  	 *
98  	 * @param pQualifiers
99  	 */
100 	public CIMQualifiedElementInterfaceImpl(CIMQualifier<?>[] pQualifiers) {
101 		setQualis(pQualifiers);
102 	}
103 
104 	/**
105 	 * Ctor. This constructor modifies the qualifier list according to the
106 	 * pIsKeyed flag.
107 	 *
108 	 * @param pQualifiers
109 	 * @param pIsKeyed
110 	 */
111 	public CIMQualifiedElementInterfaceImpl(CIMQualifier<?>[] pQualifiers, boolean pIsKeyed) {
112 		this(pQualifiers, pIsKeyed, false);
113 	}
114 
115 	/**
116 	 * Ctor. This constructor is able to not remove the EmbeddedObject
117 	 * qualifier. It is useful for the XML parser to parse EmbeddedObject
118 	 * qualified elements without values.
119 	 *
120 	 * @param pQualifiers
121 	 * @param pIsKeyed
122 	 * @param pKeepEmbObj
123 	 */
124 	public CIMQualifiedElementInterfaceImpl(CIMQualifier<?>[] pQualifiers, boolean pIsKeyed, boolean pKeepEmbObj) {
125 		this(pQualifiers, pIsKeyed, pKeepEmbObj, false);
126 	}
127 
128 	/**
129 	 * Ctor. This constructor is able to not remove the EmbeddedObject
130 	 * qualifier. It is useful for the XML parser to parse EmbeddedObject
131 	 * qualified elements without values. It also adds or removes the
132 	 * Association qualifier depending on the value of pIsAssociation.
133 	 *
134 	 * @param pQualifiers
135 	 * @param pIsKeyed
136 	 * @param pKeepEmbObj
137 	 * @param pIsAssociation
138 	 */
139 	public CIMQualifiedElementInterfaceImpl(
140 		CIMQualifier<?>[] pQualifiers,
141 		boolean pIsKeyed,
142 		boolean pKeepEmbObj,
143 		boolean pIsAssociation
144 	) {
145 		if (pKeepEmbObj) {
146 			this.iQualis = (CIMQualifier[]) CIMElementSorter.sort(pQualifiers);
147 			this.iEmbeddedObject = CIMElementSorter.findIdx(this.iQualis, "EmbeddedObject") >= 0;
148 		} else {
149 			setQualis(pQualifiers);
150 		}
151 		setBoolQualifier(KEY, pIsKeyed);
152 		setBoolQualifier(ASSOCIATION, pIsAssociation);
153 	}
154 
155 	/**
156 	 * @see java.lang.Object#equals(java.lang.Object)
157 	 */
158 	@Override
159 	public boolean equals(Object pObj) {
160 		if (!(pObj instanceof CIMQualifiedElementInterfaceImpl)) return false;
161 		CIMQualifiedElementInterfaceImpl that = (CIMQualifiedElementInterfaceImpl) pObj;
162 		return Arrays.equals(getQualifiers(), that.getQualifiers());
163 	}
164 
165 	/**
166 	 * @see java.lang.Object#hashCode()
167 	 */
168 	@Override
169 	public int hashCode() {
170 		return Arrays.hashCode(getQualifiers());
171 	}
172 
173 	/**
174 	 * Sets the Qualifiers. If there is an EmbeddedObject qualifier,
175 	 * corresponding flag is set.
176 	 *
177 	 * @param pQualiA
178 	 */
179 	private void setQualis(CIMQualifier<?>[] pQualiA) {
180 		pQualiA = (CIMQualifier[]) CIMElementSorter.sort(pQualiA);
181 		int rmIdx = CIMElementSorter.findIdx(pQualiA, "EmbeddedObject");
182 		if (rmIdx < 0) {
183 			this.iQualis = pQualiA;
184 			return;
185 		}
186 		this.iEmbeddedObject = true;
187 		this.iQualis = pQualiA;
188 	}
189 
190 	/**
191 	 * if pValue is false and boolean qualifier exists it is removed.<br>
192 	 * if pValue is true and boolean qualifier exists, it's value is changed to
193 	 * true, if boolean qualifier doesn't exist it is added.
194 	 *
195 	 * @param pQuali
196 	 * @param pValue
197 	 */
198 	private void setBoolQualifier(CIMQualifier<Boolean> pQuali, boolean pValue) {
199 		int idx = CIMElementSorter.findIdx(this.iQualis, pQuali.getName());
200 		if (pValue) {
201 			if (idx < 0) {
202 				// insert the qualifier
203 				// idx=-insertIdx-1
204 				// insertIdx=-idx-1;
205 				insertQuali(pQuali, -idx - 1);
206 			} else if (!pQuali.getValue().equals(this.iQualis[idx].getValue())) {
207 				// change the qualifier if value different
208 				this.iQualis[idx] = pQuali;
209 			}
210 		} else {
211 			if (idx > 0) {
212 				// remove the existing qualifier
213 				removeQuali(idx);
214 			}
215 		}
216 	}
217 
218 	private void insertQuali(CIMQualifier<Boolean> pQuali, int idx) {
219 		int origLength = this.iQualis == null ? 0 : this.iQualis.length;
220 		CIMQualifier<?>[] qualis = new CIMQualifier[origLength + 1];
221 		int srcIdx = 0, dstIdx = 0;
222 		while (srcIdx < idx) qualis[dstIdx++] = this.iQualis[srcIdx++];
223 		qualis[dstIdx++] = pQuali;
224 		while (srcIdx < origLength) qualis[dstIdx++] = this.iQualis[srcIdx++];
225 		this.iQualis = qualis;
226 	}
227 
228 	private void removeQuali(int idx) {
229 		CIMQualifier<?>[] qualis = new CIMQualifier[this.iQualis.length - 1];
230 		int srcIdx = 0, dstIdx = 0;
231 		while (srcIdx < idx) qualis[dstIdx++] = this.iQualis[srcIdx++];
232 		++srcIdx;
233 		while (srcIdx < this.iQualis.length) qualis[dstIdx++] = this.iQualis[srcIdx++];
234 		this.iQualis = qualis;
235 	}
236 
237 	/*
238 	 * CIMQualifier( "Key", CIMDataType.BOOLEAN_T, new Boolean(true),
239 	 * CIMFlavor.DISABLEOVERRIDE );
240 	 */
241 
242 	/**
243 	 * Returns true if the "key" Qualifier with true value presents.
244 	 *
245 	 * @return true/false
246 	 */
247 	public boolean isKeyed() {
248 		return hasQualifierValue("key", Boolean.TRUE);
249 	}
250 
251 	/**
252 	 * Returns true if the "EmbeddedObject" qualifier with true value presents.
253 	 *
254 	 * @return true/false
255 	 */
256 	public boolean isEmbeddedObject() {
257 		return this.iEmbeddedObject;
258 	}
259 
260 	/**
261 	 * @see org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface#getQualifier(int)
262 	 */
263 	public CIMQualifier<?> getQualifier(int pIndex) {
264 		return this.iQualis[pIndex];
265 	}
266 
267 	/**
268 	 * @see org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface#getQualifier(java.lang.String)
269 	 */
270 	public CIMQualifier<?> getQualifier(String pName) {
271 		return (CIMQualifier<?>) CIMElementSorter.find(this.iQualis, pName);
272 	}
273 
274 	/**
275 	 * @see org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface#getQualifierCount()
276 	 */
277 	public int getQualifierCount() {
278 		return this.iQualis == null ? 0 : this.iQualis.length;
279 	}
280 
281 	/**
282 	 * @see org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface#getQualifierValue(java.lang.String)
283 	 */
284 	public Object getQualifierValue(String pName) {
285 		CIMQualifier<?> quali = getQualifier(pName);
286 		if (quali == null) return null;
287 		return quali.getValue();
288 	}
289 
290 	/**
291 	 * @see org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface#getQualifiers()
292 	 */
293 	public CIMQualifier<?>[] getQualifiers() {
294 		return getQualifiers(false);
295 	}
296 
297 	/**
298 	 * getQualifiers - helps filtering based on the propagated flag.
299 	 *
300 	 * @param pLocalOnly
301 	 * @return CIMQualifier[]
302 	 */
303 	public CIMQualifier<?>[] getQualifiers(boolean pLocalOnly) {
304 		if (this.iQualis == null) return EMPTY_QA;
305 		if (!pLocalOnly) return this.iQualis;
306 		if (this.iLocalOnlyQualis == null) {
307 			ArrayList<CIMQualifier<?>> qualiL = new ArrayList<CIMQualifier<?>>(this.iQualis.length);
308 			for (int i = 0; i < this.iQualis.length; i++) if (!this.iQualis[i].isPropagated()) qualiL.add(this.iQualis[i]);
309 			this.iLocalOnlyQualis = qualiL.toArray(new CIMQualifier[qualiL.size()]);
310 		}
311 		return this.iLocalOnlyQualis;
312 	}
313 
314 	/**
315 	 * @see org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface#hasQualifier(java.lang.String)
316 	 */
317 	public boolean hasQualifier(String pName) {
318 		return getQualifier(pName) != null;
319 	}
320 
321 	/**
322 	 * @see org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface#hasQualifierValue(java.lang.String,
323 	 *      java.lang.Object)
324 	 */
325 	public boolean hasQualifierValue(String pName, Object pValue) {
326 		if (!hasQualifier(pName)) return false;
327 		Object value = getQualifierValue(pName);
328 		return value == null ? pValue == null : value.equals(pValue);
329 	}
330 }