View Javadoc
1   /*
2    * Copyright 2013 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.juddi.v3.client.compare;
17  
18  import javax.xml.datatype.DatatypeConfigurationException;
19  import javax.xml.datatype.DatatypeConstants;
20  import javax.xml.datatype.DatatypeFactory;
21  import javax.xml.datatype.Duration;
22  import javax.xml.datatype.XMLGregorianCalendar;
23  import org.uddi.api_v3.InstanceDetails;
24  import org.uddi.api_v3.TModelInstanceDetails;
25  
26  /**
27   * Compares two UDDI TModelInstanceDetails, searching for a specific tModel key,
28   * then parsing to the selected data type, then comparing.
29   *
30   * @author Alex O'Ree
31   */
32  public class TModelInstanceDetailsComparator {
33  
34      /**
35       *
36       * @param TModelKey for TModelInstanceInfo to use for comparison
37       * @param number if true, the InstanceDetails.InstanceParms will be treated
38       * like a number
39       * @param XMLdate if true, the InstanceDetails.InstanceParms will be treated
40       * like a XML Date
41       * @param XMLduration if true, the InstanceDetails.InstanceParms will be
42       * treated like a XML Gregorian Calendar
43       * @see Duration
44       * @see XMLGregorianCalendar
45       * @throws DatatypeConfigurationException
46       */
47      public TModelInstanceDetailsComparator(String TModelKey, boolean number, boolean XMLdate, boolean XMLduration) throws DatatypeConfigurationException, IllegalArgumentException {
48          if (TModelKey == null || TModelKey.length() == 0) {
49              throw new IllegalArgumentException();
50          }
51          compareField = TModelKey;
52          if (!number && !XMLdate && !XMLduration) {
53              throw new IllegalArgumentException("only one data type can be selected");
54          }
55          if (number && XMLdate && !XMLduration) {
56              throw new IllegalArgumentException("only one data type can be selected");
57          }
58          if (number && !XMLdate && XMLduration) {
59              throw new IllegalArgumentException("only one data type can be selected");
60          }
61          if (!number && XMLdate && XMLduration) {
62              throw new IllegalArgumentException("only one data type can be selected");
63          }
64          if (number && XMLdate && XMLduration) {
65              throw new IllegalArgumentException("only one data type can be selected");
66          }
67          fac = DatatypeFactory.newInstance();
68          isNumber = number;
69          isDate = XMLdate;
70          isDuration = XMLduration;
71      }
72      DatatypeFactory fac = null;
73      String compareField = null;
74      boolean isNumber = false;
75      boolean isDate = false;
76      boolean isDuration = false;
77  
78      /**
79       * Compares two non-null instances of TModelInstanceDetails by only
80       * comparing the field designated from the constructor. It will also cast or
81       * parse TModelInstanceDetails[i].InstanceDetails[k].InstanceParms to the
82       * selected data type double, XMLGregorgian or Duration, using that as a
83       * basis for comparison. If a parsing error occurs, an exception will be
84       * thrown.
85       *
86       * @param lhs
87       * @param rhs
88       * @return less than 0 if lhs < rhs, greater than 0 if lhs > rhs.
89       * @throws IllegalArgumentException if the tModel key to search for is
90       * missing, if either sides are null
91       * @throws ArrayIndexOutOfBoundsException if the values were found but could
92       * not be compared
93       */
94      public int compare(TModelInstanceDetails lhs, TModelInstanceDetails rhs) throws IllegalArgumentException, NumberFormatException, NullPointerException, ArrayIndexOutOfBoundsException {
95          if (lhs == null) {
96              throw new IllegalArgumentException("lhs");
97          }
98          if (rhs == null) {
99              throw new IllegalArgumentException("rhs");
100         }
101         if (lhs.getTModelInstanceInfo().isEmpty() || rhs.getTModelInstanceInfo().isEmpty()) {
102             throw new IllegalArgumentException("no data to compare");
103         }
104         InstanceDetails lhsc = null;
105         InstanceDetails rhsc = null;
106         for (int i = 0; i < lhs.getTModelInstanceInfo().size(); i++) {
107             if (lhs.getTModelInstanceInfo().get(i).getTModelKey().equalsIgnoreCase(compareField)) {
108                 lhsc = lhs.getTModelInstanceInfo().get(i).getInstanceDetails();
109             }
110         }
111         for (int i = 0; i < rhs.getTModelInstanceInfo().size(); i++) {
112             if (rhs.getTModelInstanceInfo().get(i).getTModelKey().equalsIgnoreCase(compareField)) {
113                 rhsc = rhs.getTModelInstanceInfo().get(i).getInstanceDetails();
114             }
115         }
116 
117         if (lhsc == null) {
118             throw new IllegalArgumentException(compareField + " not found for lhs");
119         }
120         if (rhsc == null) {
121             throw new IllegalArgumentException(compareField + " not found for rhs");
122         }
123         if (lhsc.getInstanceParms() == null) {
124             throw new IllegalArgumentException(compareField + " found lhs, but no data");
125         }
126         if (rhsc.getInstanceParms() == null) {
127             throw new IllegalArgumentException(compareField + " found rhs, but no data");
128         }
129         if (isNumber) {
130             Double l = Double.parseDouble(lhsc.getInstanceParms());
131             Double r = Double.parseDouble(rhsc.getInstanceParms());
132             return l.compareTo(r);
133         }
134 
135         if (isDate) {
136             XMLGregorianCalendar l = fac.newXMLGregorianCalendar(lhsc.getInstanceParms());
137             XMLGregorianCalendar r = fac.newXMLGregorianCalendar(rhsc.getInstanceParms());
138             //System.out.println(l.toXMLFormat() + " " + r.toXMLFormat());
139             int x = l.compare(r);
140 
141             if (x == DatatypeConstants.LESSER) {
142                 return -1;
143             }
144 
145             if (x == DatatypeConstants.GREATER) {
146                 return 1;
147             }
148             if (x == DatatypeConstants.EQUAL) {
149                 return 0;
150             }
151             throw new ArrayIndexOutOfBoundsException("cannot compare, result was " + x);
152         }
153 
154         if (isDuration) {
155             Duration l = fac.newDuration(lhsc.getInstanceParms());
156             Duration r = fac.newDuration(rhsc.getInstanceParms());
157           //  System.out.println(l.toString() + " " + r.toString());
158             int x = l.compare(r);
159 
160             if (x == DatatypeConstants.LESSER) {
161                 return -1;
162             }
163 
164             if (x == DatatypeConstants.GREATER) {
165                 return 1;
166             }
167             if (x == DatatypeConstants.EQUAL) {
168                 return 0;
169             }
170             throw new ArrayIndexOutOfBoundsException("cannot compare, result was " + x);
171         }
172 
173         return 0;
174     }
175 }