View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
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.argeo.slc.client.ui.dist.utils;
17  
18  import java.math.BigDecimal;
19  import java.util.Calendar;
20  import java.util.List;
21  
22  import javax.jcr.Node;
23  import javax.jcr.PropertyType;
24  import javax.jcr.RepositoryException;
25  import javax.jcr.Value;
26  import javax.jcr.ValueFormatException;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.argeo.eclipse.ui.GenericTableComparator;
31  import org.argeo.slc.SlcException;
32  import org.eclipse.jface.viewers.Viewer;
33  
34  /** Add ability to order by name version and version */
35  public class DistNodeViewerComparator extends GenericTableComparator {
36  	private static final long serialVersionUID = -5966120108210992211L;
37  
38  	private final static Log log = LogFactory
39  			.getLog(DistNodeViewerComparator.class);
40  
41  	// Jcr property type goes to 12
42  	public final static int NAME_VERSION_TYPE = 100;
43  	public final static int VERSION_TYPE = 101;
44  
45  	protected List<String> propertiesList;
46  	protected List<Integer> propertyTypesList;
47  	protected Integer propertyType;
48  	protected String property;
49  
50  	private NameVersionComparator nvc = new NameVersionComparator();
51  	private VersionComparator vc = new VersionComparator();
52  
53  	public DistNodeViewerComparator(int defaultColIndex, int defaultDirection,
54  			List<String> propertiesList, List<Integer> propertyTypesList) {
55  		super(defaultColIndex, defaultDirection);
56  		this.propertiesList = propertiesList;
57  		this.propertyTypesList = propertyTypesList;
58  		this.propertyIndex = defaultColIndex;
59  		this.propertyType = propertyTypesList.get(defaultColIndex);
60  		this.property = propertiesList.get(defaultColIndex);
61  		setColumn(defaultColIndex);
62  	}
63  
64  	@Override
65  	public int compare(Viewer viewer, Object e1, Object e2) {
66  		int rc = 0;
67  		long lc = 0;
68  
69  		try {
70  			Node n1 = (Node) e1;
71  			Node n2 = (Node) e2;
72  
73  			Value v1 = null;
74  			Value v2 = null;
75  			if (n1.hasProperty(property))
76  				v1 = n1.getProperty(property).getValue();
77  			if (n2.hasProperty(property))
78  				v2 = n2.getProperty(property).getValue();
79  
80  			if (v2 == null && v1 == null)
81  				return 0;
82  			else if (v2 == null)
83  				return -1;
84  			else if (v1 == null)
85  				return 1;
86  
87  			switch (propertyType) {
88  			case NAME_VERSION_TYPE:
89  				rc = nvc.compare(viewer, v1.getString(), v2.getString());
90  				break;
91  			case VERSION_TYPE:
92  				rc = vc.compare(viewer, v1.getString(), v2.getString());
93  				break;
94  			case PropertyType.STRING:
95  				rc = v1.getString().compareTo(v2.getString());
96  				break;
97  			case PropertyType.BOOLEAN:
98  				boolean b1 = v1.getBoolean();
99  				boolean b2 = v2.getBoolean();
100 				if (b1 == b2)
101 					rc = 0;
102 				else
103 					// we assume true is greater than false
104 					rc = b1 ? 1 : -1;
105 				break;
106 			case PropertyType.DATE:
107 				Calendar c1 = v1.getDate();
108 				Calendar c2 = v2.getDate();
109 				if (c1 == null || c2 == null)
110 					log.trace("undefined date");
111 				lc = c1.getTimeInMillis() - c2.getTimeInMillis();
112 				if (lc < Integer.MIN_VALUE)
113 					// rc = Integer.MIN_VALUE;
114 					rc = -1;
115 				else if (lc > Integer.MAX_VALUE)
116 					// rc = Integer.MAX_VALUE;
117 					rc = 1;
118 				else
119 					rc = (int) lc;
120 				break;
121 			case PropertyType.LONG:
122 				long l1;
123 				long l2;
124 				// FIXME sometimes an empty string is set instead of the id
125 				try {
126 					l1 = v1.getLong();
127 				} catch (ValueFormatException ve) {
128 					l1 = 0;
129 				}
130 				try {
131 					l2 = v2.getLong();
132 				} catch (ValueFormatException ve) {
133 					l2 = 0;
134 				}
135 
136 				lc = l1 - l2;
137 				if (lc < Integer.MIN_VALUE)
138 					// rc = Integer.MIN_VALUE;
139 					rc = -1;
140 				else if (lc > Integer.MAX_VALUE)
141 					// rc = Integer.MAX_VALUE;
142 					rc = 1;
143 				else
144 					rc = (int) lc;
145 				break;
146 			case PropertyType.DECIMAL:
147 				BigDecimal bd1 = v1.getDecimal();
148 				BigDecimal bd2 = v2.getDecimal();
149 				rc = bd1.compareTo(bd2);
150 				break;
151 			default:
152 				throw new SlcException(
153 						"Unimplemented comparaison for PropertyType "
154 								+ propertyType);
155 			}
156 
157 			// If descending order, flip the direction
158 			if (direction == DESCENDING) {
159 				rc = -rc;
160 			}
161 
162 		} catch (RepositoryException re) {
163 			throw new SlcException("Unexpected error "
164 					+ "while comparing nodes", re);
165 		}
166 		return rc;
167 	}
168 
169 	@Override
170 	public void setColumn(int column) {
171 		if (column == this.propertyIndex) {
172 			// Same column as last sort; toggle the direction
173 			direction = 1 - direction;
174 		} else {
175 			// New column; do a descending sort
176 			this.propertyIndex = column;
177 			this.propertyType = propertyTypesList.get(column);
178 			this.property = propertiesList.get(column);
179 			direction = ASCENDING;
180 		}
181 	}
182 }