Project

General

Profile

« Previous | Next » 

Revision 47652

cleanup

View differences:

modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/deploy.info
1
{"type_source": "SVN", "goal": "package -U -T 4C source:jar", "url": "http://svn-public.driver.research-infrastructures.eu/driver/dnet45/modules/cnr-misc-utils/trunk/", "deploy_repository": "dnet45-snapshots", "version": "4", "mail": "sandro.labruzzo@isti.cnr.it,michele.artini@isti.cnr.it, claudio.atzori@isti.cnr.it, alessia.bardi@isti.cnr.it", "deploy_repository_url": "http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-snapshots", "name": "cnr-misc-utils"}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/resources/META-INF/services/javax.xml.transform.TransformerFactory
1
net.sf.saxon.TransformerFactoryImpl
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/factory/Factory.java
1
package eu.dnetlib.miscutils.factory;
2

  
3
/**
4
 * Provides a common interface for factory objects. 
5
 * 
6
 * @author marko
7
 *
8
 * @param <T>
9
 */
10
public interface Factory<T> {
11
	/**
12
	 * returns a new instance.
13
	 * 
14
	 * @return
15
	 */
16
	T newInstance();
17
}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/hstree/TreeNode.java
1
package eu.dnetlib.miscutils.hstree;
2

  
3
import java.lang.reflect.InvocationTargetException;
4
import java.lang.reflect.ParameterizedType;
5
import java.lang.reflect.Type;
6
import java.util.ArrayList;
7
import java.util.LinkedList;
8
import java.util.List;
9
import java.util.Queue;
10

  
11
import org.apache.commons.logging.Log;
12
import org.apache.commons.logging.LogFactory;
13

  
14
/**
15
 * This class implement statically typed complete tree of finite depth. The type signature of each tree node determines
16
 * fully the depth and the types of all the children.
17
 * 
18
 * <pre>
19
 * class MyTree extends TreeNode&lt;RootPayload, L1Payload, TreeNode&lt;L1Payload, L2Payload, TreeNode&lt;L2Payload, Void, NilTreeNode&gt;&gt;&gt; {
20
 * 
21
 * }
22
 * </pre>
23
 * 
24
 * However since java doesn't have type inferencing we'll have to write often the full type of intermediate nodes,
25
 * especially during tree construction. Thus it's recommended that you split the chain into a number of dummy classes,
26
 * serving only to the purpuse of declaring the type chain:
27
 * 
28
 * <pre>
29
 * class MyTree extends TreeNode&lt;RootPayload, L1Payload, L1Tree&gt; {
30
 * }
31
 * 
32
 * class L1Tree extends TreeNode&lt;L1Payload, L2Payload, L2Tree&gt; {
33
 * }
34
 * 
35
 * class L2Tree extends TreeNode&lt;L2Payload, Void, NilTreeNode&gt; {
36
 * }
37
 * </pre>
38
 * 
39
 * NOTE: you could keep the whole definition inside a single file using inner classes.
40
 * 
41
 * @author marko
42
 * 
43
 * @param <T>
44
 *            Type of the payload (or resource)
45
 * @param <N>
46
 *            Type of the next level payload
47
 * @param <C>
48
 *            Type of the next level node (another TreeNode)
49
 */
50
public class TreeNode<T, N, V, C extends TreeNode<N, ?, V, ?>> {
51

  
52
	public static final String CHILDR_UNDER_LEAF = "cannot create children under leaf nodes";
53

  
54
	private static final Log log = LogFactory.getLog(TreeNode.class); // NOPMD by marko on 11/24/08 5:02 PM
55

  
56
	T resource;
57
	List<C> children = new ArrayList<C>();
58
	transient Class<? extends C> childNodeType = autoChildNodeType(getClass());
59

  
60
	/**
61
	 * Default constructor doesn't set the payload. This is used internally to construct a node. We cannot use the
62
	 * <code>TreeNode(T resource)</code> constructor only because it would force any implementor of "alias" subclasses
63
	 * of TreeNode to provide a dummy implementation of the constructor calling <code>super(resource)</code>
64
	 * 
65
	 * However the constructor is protected because users should only create objects through <code>addChild</code> or in
66
	 * alternative they should provide they own constructor ovverrides.
67
	 */
68
	protected TreeNode() {
69
		// no action
70
	}
71

  
72
	/**
73
	 * However the constructor is protected because users should only create objects through <code>addChild</code> or in
74
	 * alternative they should provide they own constructor ovverrides.
75
	 * 
76
	 * @param resource
77
	 *            payload
78
	 */
79
	protected TreeNode(final T resource) {
80
		this.resource = resource;
81
	}
82

  
83
	/**
84
	 * Call this method to add a child node.
85
	 * 
86
	 * Only the payload is needed, the tree node will be constructed automatically and it will be returned.
87
	 * 
88
	 * <pre>
89
	 * L1Child c1 = root.addChild(new L1Resource());
90
	 * c1.addChild(new L2Resource());
91
	 * c1.addChild(new L2Resource()).addChild(new L3Resource());
92
	 * </pre>
93
	 * 
94
	 * @param resource
95
	 *            payload
96
	 * @return the new node
97
	 */
98
	@SuppressWarnings("unchecked")
99
	public C addChild(final N resource) {
100
		try {
101
			if (childNodeType.equals(NilTreeNode.class))
102
				throw new IllegalStateException(CHILDR_UNDER_LEAF);
103

  
104
			C test;
105
			try {
106
				test = childNodeType.newInstance();
107
				test.setResource(resource);
108
			} catch (InstantiationException e) {
109
				/*
110
				 * handle the situation when someone wants to create a one argument constructor hiding the default
111
				 * constructor provided by the base class. Nodes should normally be constructed using addChild but we
112
				 * don't want to force users to do it, and if they do it they shouldn't be punished with obscure
113
				 * InstantiationException caused by our evil usage of reflection. Of course we should do much more here
114
				 * in order to be more robust in the general case.
115
				 */
116
				try {
117
					test = (C) childNodeType.getConstructors()[0].newInstance(resource); // NOPMD
118
				} catch (InvocationTargetException e1) {
119
					throw new IllegalStateException(e1);
120
				} catch (InstantiationException e1) {
121
					throw new IllegalStateException(e1);
122
				}
123
			}
124

  
125
			getChildren().add(test);
126
			return test;
127
		} catch (IllegalArgumentException e) {
128
			throw new IllegalStateException(e);
129
		} catch (SecurityException e) {
130
			throw new IllegalStateException(e);
131
		} catch (IllegalAccessException e) {
132
			throw new IllegalStateException(e);
133
		}
134
	}
135

  
136
	/**
137
	 * This method is especially useful for leaf nodes when you want to append several children to the same parent node,
138
	 * without having to declare a temporary variable to hold the parent node (which could have long and ugly type)
139
	 * 
140
	 * @param resource
141
	 * @return the parent node
142
	 */
143
	public TreeNode<T, N, V, C> appendChild(final N resource) {
144
		addChild(resource);
145
		return this;
146
	}
147

  
148
	/**
149
	 * This method applies a visitor to all nodes in a breadth first fashon
150
	 * 
151
	 * Currently null payloads are skipped
152
	 * 
153
	 * @see Visitor
154
	 * @param visitor
155
	 */
156
	public void breadthFirst(final V visitor) {
157
		final Queue<TreeNode<?, ?, V, ?>> queue = new LinkedList<TreeNode<?, ?, V, ?>>();
158

  
159
		queue.add(this);
160
		while (!queue.isEmpty()) {
161
			final TreeNode<?, ?, V, ?> current = queue.remove();
162
			log.info("visiting " + current);
163
			current.accept(visitor);
164
			queue.addAll(current.getChildren());
165
		}
166

  
167
	}
168

  
169
	/**
170
	 * depth first.
171
	 * 
172
	 * Currently null payloads are skipped
173
	 * 
174
	 * @see Visitor
175
	 * @param Visitor
176
	 */
177
	public void depthFirst(final V visitor) {
178
		baseDepthFirst(visitor);
179
	}
180

  
181
	public void baseDepthFirst(final V visitor) {
182
		accept(visitor);
183

  
184
		for (C el : children)
185
			el.baseDepthFirst(visitor);
186
	}
187

  
188
	/**
189
	 * For the curious, this method takes care of retrieving the runtime type information for the tree node element
190
	 * declared for children nodes.
191
	 * 
192
	 * Because of java type erasure, this is not strictly needed for making this kind of tree work, but it's needed if
193
	 * we want to enable people typing ugly long signatures and use type aliases as described in the class
194
	 * documentation; otherwise a cast exception would occur.
195
	 * 
196
	 * Aargh, any serious language which permits type polymorphysm should have a type alias feature
197
	 * 
198
	 * @param clazz
199
	 *            the class object of this class
200
	 * @return the class object of the node element describing children
201
	 */
202
	@SuppressWarnings({ "unchecked", "rawtypes"})
203
	protected Class<? extends C> autoChildNodeType(final Class<? extends TreeNode> clazz) {
204

  
205
		final Type superType = clazz.getGenericSuperclass();
206

  
207
		if (superType instanceof ParameterizedType) {
208
			final ParameterizedType paramSuperType = (ParameterizedType) superType;
209

  
210
			int argumentIndex;
211
			if (paramSuperType.getRawType() == TreeNode.class)
212
				argumentIndex = 3;
213
			else
214
				argumentIndex = 2;
215
				
216

  
217
			final Type argument = (paramSuperType).getActualTypeArguments()[argumentIndex];
218

  
219
			return getRawType(argument);
220
		} else {
221
			return autoChildNodeType((Class<? extends TreeNode>) superType);
222
		}
223
	}
224

  
225
	@SuppressWarnings("unchecked")
226
	protected <X> X getRawType(final Type type) {
227
		if (type instanceof ParameterizedType)
228
			return (X) ((ParameterizedType) type).getRawType();
229
		return (X) type;
230
	}
231

  
232
	public List<C> getChildren() {
233
		return children;
234
	}
235

  
236
	public void setChildren(final List<C> children) {
237
		this.children = children;
238
	}
239

  
240
	public T getResource() {
241
		return resource;
242
	}
243

  
244
	public void setResource(final T resource) {
245
		this.resource = resource;
246
	}
247

  
248
	public void accept(final V dummy) {
249
		log.fatal("should be ovverriden");
250
	}
251

  
252
}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/hstree/NilTreeNode.java
1
package eu.dnetlib.miscutils.hstree;
2

  
3
/**
4
 * This is the terminator node in a tree definition chain:
5
 * 
6
 * TreeNode<L0, L1, TreeNode<L1, L2, TreeNode<L2, Void, NilTreeNode>>>
7
 * 
8
 * Note the use of "Void" as the next-resource-parameter value in the last level.
9
 * 
10
 * 
11
 * @author marko
12
 * 
13
 */
14
abstract public class NilTreeNode<V> extends TreeNode<Void, Void, V, TreeNode<Void, ?, V, ?>> { // NOPMD
15

  
16
}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/datetime/DateUtils.java
1
package eu.dnetlib.miscutils.datetime;
2

  
3
import java.text.ParseException;
4
import java.text.SimpleDateFormat;
5
import java.util.Date;
6
import java.util.Locale;
7

  
8
/**
9
 * various date utilities.
10
 * 
11
 * @author michele
12
 * 
13
 */
14
public class DateUtils {
15

  
16
	private static final SimpleDateFormat ISO8601FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);
17

  
18
	private transient final Date date;
19

  
20
	public DateUtils() {
21
		this.date = new Date();
22
	}
23

  
24
	public DateUtils(final Date date) {
25
		this.date = (Date) date.clone();
26
	}
27

  
28
	public String getDateAsISO8601String() {
29
		String result;
30
		synchronized (ISO8601FORMAT) {
31
			result = ISO8601FORMAT.format(this.date);
32
		}
33

  
34
		//convert YYYYMMDDTHH:mm:ss+HH00 into YYYYMMDDTHH:mm:ss+HH:00
35
		//- note the added colon for the Timezone
36
		return result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
37
	}
38

  
39
	public Long getPrecisionTime() {
40
		return this.date.getTime();
41
	}
42

  
43
	public static long now() {
44
		return new Date().getTime();
45
	}
46

  
47
	public static String now_ISO8601() { // NOPMD
48
		String result;
49
		synchronized (ISO8601FORMAT) {
50
			result = ISO8601FORMAT.format(new Date());
51
		}
52
		//convert YYYYMMDDTHH:mm:ss+HH00 into YYYYMMDDTHH:mm:ss+HH:00
53
		//- note the added colon for the Timezone
54
		return result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
55
	}
56

  
57
	/**
58
	 * parses a iso8601 date into a date.
59
	 * 
60
	 * @param date
61
	 *            string iso8601 date
62
	 * @return date object
63
	 */
64
	public Date parse(final String dateArg) {
65
		String date = dateArg;
66

  
67
		if ("".equals(date))
68
			return null;
69

  
70
		try {
71
			if (date.endsWith("Z")) {
72
				date = date.replace("Z", "+0000");
73
			} else if (date.length() < 20) {
74
				date += "+0000"; // NOPMD
75
			} else {
76
				final String end = date.substring(date.length() - 3);
77
				date = date.substring(0, date.length() - 3) + end.replace(":", "");
78
			}
79

  
80
			synchronized (ISO8601FORMAT) {
81
				return ISO8601FORMAT.parse(date);
82
			}
83
		} catch (ParseException e) {
84
			throw new IllegalStateException("invalid iso8601 date '" + dateArg + "' (even after normalizing it to '" + date + "')");
85
		}
86
	}
87

  
88
	public static String calculate_ISO8601(long l) {
89
		String result = ISO8601FORMAT.format(new Date(l));
90
		// convert YYYYMMDDTHH:mm:ss+HH00 into YYYYMMDDTHH:mm:ss+HH:00
91
		//- note the added colon for the Timezone
92
		result = result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
93
		return result;
94
	}
95

  
96
	/**
97
	 * Extracts the duration part of a ISO8601 formatted date. Duration part is the part after the 'T'.
98
	 * 
99
	 * @param dateArg
100
	 * @return
101
	 */
102
	public String getDuration(final String dateArg) {
103
		String[] splitted = dateArg.split("T");
104
		if (splitted.length == 1)
105
			return "0";
106
		else
107
			return splitted[1];
108
	}
109
}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/datetime/HumanTime.java
1
package eu.dnetlib.miscutils.datetime;
2

  
3
/*
4
 * HumanTime.java
5
 * 
6
 * Created on 06.10.2008
7
 * 
8
 * Copyright (c) 2008 Johann Burkard (<mailto:jb@eaio.com>) <http://eaio.com>
9
 * 
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
11
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
12
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
13
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
14
 * 
15
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
16
 * Software.
17
 * 
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
19
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 * 
23
 */
24

  
25
import java.io.Externalizable;
26
import java.io.IOException;
27
import java.io.ObjectInput;
28
import java.io.ObjectOutput;
29
import java.util.Iterator;
30

  
31
/**
32
 * HumanTime parses and formats time deltas for easier reading by humans. It can format time information without losing
33
 * information but its main purpose is to generate more easily understood approximations. <h3>Using HumanTime</h3>
34
 * <p>
35
 * Use HumanTime by creating an instance that contains the time delta ({@link HumanTime#HumanTime(long)}), create an
36
 * empty instance through ({@link HumanTime#HumanTime()}) and set the delta using the {@link #y()}, {@link #d()},
37
 * {@link #h()}, {@link #s()} and {@link #ms()} methods or parse a {@link CharSequence} representation (
38
 * {@link #eval(CharSequence)}). Parsing ignores whitespace and is case insensitive.
39
 * </p>
40
 * <h3>HumanTime format</h3>
41
 * <p>
42
 * HumanTime will format time deltas in years ("y"), days ("d"), hours ("h"), minutes ("m"), seconds ("s") and
43
 * milliseconds ("ms"), separated by a blank character. For approximate representations, the time delta will be round up
44
 * or down if necessary.
45
 * </p>
46
 * <h3>HumanTime examples</h3>
47
 * <ul>
48
 * <li>HumanTime.eval("1 d 1d 2m 3m").getExactly() = "2 d 5 m"</li>
49
 * <li>HumanTime.eval("2m8d2h4m").getExactly() = "8 d 2 h 6 m"</li>
50
 * <li>HumanTime.approximately("2 d 8 h 20 m 50 s") = "2 d 8 h"</li>
51
 * <li>HumanTime.approximately("55m") = "1 h"</li>
52
 * </ul>
53
 * <h3>Implementation details</h3>
54
 * <ul>
55
 * <li>The time delta can only be increased.</li>
56
 * <li>Instances of this class are thread safe.</li>
57
 * <li>Getters using the Java Beans naming conventions are provided for use in environments like JSP or with expression
58
 * languages like OGNL. See {@link #getApproximately()} and {@link #getExactly()}.</li>
59
 * <li>To keep things simple, a year consists of 365 days.</li>
60
 * </ul>
61
 * 
62
 * @author <a href="mailto:jb@eaio.com">Johann Burkard</a>
63
 * @version $Id: HumanTime.java 323 2008-10-08 19:06:22Z Johann $
64
 * @see #eval(CharSequence)
65
 * @see #approximately(CharSequence)
66
 * @see <a href="http://johannburkard.de/blog/programming/java/date-formatting-parsing-humans-humantime.html">Date
67
 *      Formatting and Parsing for Humans in Java with HumanTime</a>
68
 */
69
public class HumanTime implements Externalizable, Comparable<HumanTime>, Cloneable {
70

  
71
	/**
72
	 * The serial version UID.
73
	 */
74
	private static final long serialVersionUID = 5179328390732826722L;
75

  
76
	/**
77
	 * One second.
78
	 */
79
	private static final long SECOND = 1000;
80

  
81
	/**
82
	 * One minute.
83
	 */
84
	private static final long MINUTE = SECOND * 60;
85

  
86
	/**
87
	 * One hour.
88
	 */
89
	private static final long HOUR = MINUTE * 60;
90

  
91
	/**
92
	 * One day.
93
	 */
94
	private static final long DAY = HOUR * 24;
95

  
96
	/**
97
	 * One year.
98
	 */
99
	private static final long YEAR = DAY * 365;
100

  
101
	/**
102
	 * Percentage of what is round up or down.
103
	 */
104
	private static final int CEILING_PERCENTAGE = 15;
105

  
106
	/**
107
	 * Parsing state.
108
	 */
109
	static enum State {
110

  
111
		NUMBER, IGNORED, UNIT
112

  
113
	}
114

  
115
	static State getState(char c) {
116
		State out;
117
		switch (c) {
118
		case '0':
119
		case '1':
120
		case '2':
121
		case '3':
122
		case '4':
123
		case '5':
124
		case '6':
125
		case '7':
126
		case '8':
127
		case '9':
128
			out = State.NUMBER;
129
			break;
130
		case 's':
131
		case 'm':
132
		case 'h':
133
		case 'd':
134
		case 'y':
135
		case 'S':
136
		case 'M':
137
		case 'H':
138
		case 'D':
139
		case 'Y':
140
			out = State.UNIT;
141
			break;
142
		default:
143
			out = State.IGNORED;
144
		}
145
		return out;
146
	}
147

  
148
	/**
149
	 * Parses a {@link CharSequence} argument and returns a {@link HumanTime} instance.
150
	 * 
151
	 * @param s
152
	 *            the char sequence, may not be <code>null</code>
153
	 * @return an instance, never <code>null</code>
154
	 */
155
	public static HumanTime eval(final CharSequence s) {
156
		HumanTime out = new HumanTime(0L);
157

  
158
		int num = 0;
159

  
160
		int start = 0;
161
		int end = 0;
162

  
163
		State oldState = State.IGNORED;
164

  
165
		for (char c : new Iterable<Character>() {
166

  
167
			/**
168
			 * @see java.lang.Iterable#iterator()
169
			 */
170
			@Override
171
			public Iterator<Character> iterator() {
172
				return new Iterator<Character>() {
173

  
174
					private int p = 0;
175

  
176
					/**
177
					 * @see java.util.Iterator#hasNext()
178
					 */
179
					@Override
180
					public boolean hasNext() {
181
						return p < s.length();
182
					}
183

  
184
					/**
185
					 * @see java.util.Iterator#next()
186
					 */
187
					@Override
188
					public Character next() {
189
						return s.charAt(p++);
190
					}
191

  
192
					/**
193
					 * @see java.util.Iterator#remove()
194
					 */
195
					@Override
196
					public void remove() {
197
						throw new UnsupportedOperationException();
198
					}
199

  
200
				};
201
			}
202

  
203
		}) {
204
			State newState = getState(c);
205
			if (oldState != newState) {
206
				if (oldState == State.NUMBER && (newState == State.IGNORED || newState == State.UNIT)) {
207
					num = Integer.parseInt(s.subSequence(start, end).toString());
208
				} else if (oldState == State.UNIT && (newState == State.IGNORED || newState == State.NUMBER)) {
209
					out.nTimes(s.subSequence(start, end).toString(), num);
210
					num = 0;
211
				}
212
				start = end;
213
			}
214
			++end;
215
			oldState = newState;
216
		}
217
		if (oldState == State.UNIT) {
218
			out.nTimes(s.subSequence(start, end).toString(), num);
219
		}
220

  
221
		return out;
222
	}
223

  
224
	/**
225
	 * Parses and formats the given char sequence, preserving all data.
226
	 * <p>
227
	 * Equivalent to <code>eval(in).getExactly()</code>
228
	 * 
229
	 * @param in
230
	 *            the char sequence, may not be <code>null</code>
231
	 * @return a formatted String, never <code>null</code>
232
	 */
233
	public static String exactly(CharSequence in) {
234
		return eval(in).getExactly();
235
	}
236

  
237
	/**
238
	 * Formats the given time delta, preserving all data.
239
	 * <p>
240
	 * Equivalent to <code>new HumanTime(in).getExactly()</code>
241
	 * 
242
	 * @param l
243
	 *            the time delta
244
	 * @return a formatted String, never <code>null</code>
245
	 */
246
	public static String exactly(long l) {
247
		return new HumanTime(l).getExactly();
248
	}
249

  
250
	/**
251
	 * Parses and formats the given char sequence, potentially removing some data to make the output easier to
252
	 * understand.
253
	 * <p>
254
	 * Equivalent to <code>eval(in).getApproximately()</code>
255
	 * 
256
	 * @param in
257
	 *            the char sequence, may not be <code>null</code>
258
	 * @return a formatted String, never <code>null</code>
259
	 */
260
	public static String approximately(CharSequence in) {
261
		return eval(in).getApproximately();
262
	}
263

  
264
	/**
265
	 * Formats the given time delta, preserving all data.
266
	 * <p>
267
	 * Equivalent to <code>new HumanTime(l).getApproximately()</code>
268
	 * 
269
	 * @param l
270
	 *            the time delta
271
	 * @return a formatted String, never <code>null</code>
272
	 */
273
	public static String approximately(long l) {
274
		return new HumanTime(l).getApproximately();
275
	}
276

  
277
	/**
278
	 * The time delta.
279
	 */
280
	private long delta;
281

  
282
	/**
283
	 * No-argument Constructor for HumanTime.
284
	 * <p>
285
	 * Equivalent to calling <code>new HumanTime(0L)</code>.
286
	 */
287
	public HumanTime() {
288
		this(0L);
289
	}
290

  
291
	/**
292
	 * Constructor for HumanTime.
293
	 * 
294
	 * @param delta
295
	 *            the initial time delta, interpreted as a positive number
296
	 */
297
	public HumanTime(long delta) {
298
		super();
299
		this.delta = Math.abs(delta);
300
	}
301

  
302
	private void nTimes(String unit, int n) {
303
		if ("ms".equalsIgnoreCase(unit)) {
304
			ms(n);
305
		} else if ("s".equalsIgnoreCase(unit)) {
306
			s(n);
307
		} else if ("m".equalsIgnoreCase(unit)) {
308
			m(n);
309
		} else if ("h".equalsIgnoreCase(unit)) {
310
			h(n);
311
		} else if ("d".equalsIgnoreCase(unit)) {
312
			d(n);
313
		} else if ("y".equalsIgnoreCase(unit)) {
314
			y(n);
315
		}
316
	}
317

  
318
	private long upperCeiling(long x) {
319
		return (x / 100) * (100 - CEILING_PERCENTAGE);
320
	}
321

  
322
	private long lowerCeiling(long x) {
323
		return (x / 100) * CEILING_PERCENTAGE;
324
	}
325

  
326
	private String ceil(long d, long n) {
327
		return Integer.toString((int) Math.ceil((double) d / n));
328
	}
329

  
330
	private String floor(long d, long n) {
331
		return Integer.toString((int) Math.floor((double) d / n));
332
	}
333

  
334
	/**
335
	 * Adds one year to the time delta.
336
	 * 
337
	 * @return this HumanTime object
338
	 */
339
	public HumanTime y() {
340
		return y(1);
341
	}
342

  
343
	/**
344
	 * Adds n years to the time delta.
345
	 * 
346
	 * @param n
347
	 *            n
348
	 * @return this HumanTime object
349
	 */
350
	public HumanTime y(int n) {
351
		delta += YEAR * Math.abs(n);
352
		return this;
353
	}
354

  
355
	/**
356
	 * Adds one day to the time delta.
357
	 * 
358
	 * @return this HumanTime object
359
	 */
360
	public HumanTime d() {
361
		return d(1);
362
	}
363

  
364
	/**
365
	 * Adds n days to the time delta.
366
	 * 
367
	 * @param n
368
	 *            n
369
	 * @return this HumanTime object
370
	 */
371
	public HumanTime d(int n) {
372
		delta += DAY * Math.abs(n);
373
		return this;
374
	}
375

  
376
	/**
377
	 * Adds one hour to the time delta.
378
	 * 
379
	 * @return this HumanTime object
380
	 */
381
	public HumanTime h() {
382
		return h(1);
383
	}
384

  
385
	/**
386
	 * Adds n hours to the time delta.
387
	 * 
388
	 * @param n
389
	 *            n
390
	 * @return this HumanTime object
391
	 */
392
	public HumanTime h(int n) {
393
		delta += HOUR * Math.abs(n);
394
		return this;
395
	}
396

  
397
	/**
398
	 * Adds one month to the time delta.
399
	 * 
400
	 * @return this HumanTime object
401
	 */
402
	public HumanTime m() {
403
		return m(1);
404
	}
405

  
406
	/**
407
	 * Adds n months to the time delta.
408
	 * 
409
	 * @param n
410
	 *            n
411
	 * @return this HumanTime object
412
	 */
413
	public HumanTime m(int n) {
414
		delta += MINUTE * Math.abs(n);
415
		return this;
416
	}
417

  
418
	/**
419
	 * Adds one second to the time delta.
420
	 * 
421
	 * @return this HumanTime object
422
	 */
423
	public HumanTime s() {
424
		return s(1);
425
	}
426

  
427
	/**
428
	 * Adds n seconds to the time delta.
429
	 * 
430
	 * @param n
431
	 *            seconds
432
	 * @return this HumanTime object
433
	 */
434
	public HumanTime s(int n) {
435
		delta += SECOND * Math.abs(n);
436
		return this;
437
	}
438

  
439
	/**
440
	 * Adds one millisecond to the time delta.
441
	 * 
442
	 * @return this HumanTime object
443
	 */
444
	public HumanTime ms() {
445
		return ms(1);
446
	}
447

  
448
	/**
449
	 * Adds n milliseconds to the time delta.
450
	 * 
451
	 * @param n
452
	 *            n
453
	 * @return this HumanTime object
454
	 */
455
	public HumanTime ms(int n) {
456
		delta += Math.abs(n);
457
		return this;
458
	}
459

  
460
	/**
461
	 * Returns a human-formatted representation of the time delta.
462
	 * 
463
	 * @return a formatted representation of the time delta, never <code>null</code>
464
	 */
465
	public String getExactly() {
466
		return getExactly(new StringBuilder()).toString();
467
	}
468

  
469
	/**
470
	 * Appends a human-formatted representation of the time delta to the given {@link Appendable} object.
471
	 * 
472
	 * @param <T>
473
	 *            the return type
474
	 * @param a
475
	 *            the Appendable object, may not be <code>null</code>
476
	 * @return the given Appendable object, never <code>null</code>
477
	 */
478
	public <T extends Appendable> T getExactly(T a) {
479
		try {
480
			boolean prependBlank = false;
481
			long d = delta;
482
			if (d >= YEAR) {
483
				a.append(floor(d, YEAR));
484
				a.append(' ');
485
				a.append('y');
486
				prependBlank = true;
487
			}
488
			d %= YEAR;
489
			if (d >= DAY) {
490
				if (prependBlank) {
491
					a.append(' ');
492
				}
493
				a.append(floor(d, DAY));
494
				a.append(' ');
495
				a.append('d');
496
				prependBlank = true;
497
			}
498
			d %= DAY;
499
			if (d >= HOUR) {
500
				if (prependBlank) {
501
					a.append(' ');
502
				}
503
				a.append(floor(d, HOUR));
504
				a.append(' ');
505
				a.append('h');
506
				prependBlank = true;
507
			}
508
			d %= HOUR;
509
			if (d >= MINUTE) {
510
				if (prependBlank) {
511
					a.append(' ');
512
				}
513
				a.append(floor(d, MINUTE));
514
				a.append(' ');
515
				a.append('m');
516
				prependBlank = true;
517
			}
518
			d %= MINUTE;
519
			if (d >= SECOND) {
520
				if (prependBlank) {
521
					a.append(' ');
522
				}
523
				a.append(floor(d, SECOND));
524
				a.append(' ');
525
				a.append('s');
526
				prependBlank = true;
527
			}
528
			d %= SECOND;
529
			if (d > 0) {
530
				if (prependBlank) {
531
					a.append(' ');
532
				}
533
				a.append(Integer.toString((int) d));
534
				a.append(' ');
535
				a.append('m');
536
				a.append('s');
537
			}
538
		} catch (IOException ex) {
539
			// What were they thinking...
540
		}
541
		return a;
542
	}
543

  
544
	/**
545
	 * Returns an approximate, human-formatted representation of the time delta.
546
	 * 
547
	 * @return a formatted representation of the time delta, never <code>null</code>
548
	 */
549
	public String getApproximately() {
550
		return getApproximately(new StringBuilder()).toString();
551
	}
552

  
553
	/**
554
	 * Appends an approximate, human-formatted representation of the time delta to the given {@link Appendable} object.
555
	 * 
556
	 * @param <T>
557
	 *            the return type
558
	 * @param a
559
	 *            the Appendable object, may not be <code>null</code>
560
	 * @return the given Appendable object, never <code>null</code>
561
	 */
562
	public <T extends Appendable> T getApproximately(T a) {
563

  
564
		try {
565
			int parts = 0;
566
			boolean rounded = false;
567
			boolean prependBlank = false;
568
			long d = delta;
569
			long mod = d % YEAR;
570

  
571
			if (mod >= upperCeiling(YEAR)) {
572
				a.append(ceil(d, YEAR));
573
				a.append(' ');
574
				a.append('y');
575
				++parts;
576
				rounded = true;
577
				prependBlank = true;
578
			} else if (d >= YEAR) {
579
				a.append(floor(d, YEAR));
580
				a.append(' ');
581
				a.append('y');
582
				++parts;
583
				rounded = mod <= lowerCeiling(YEAR);
584
				prependBlank = true;
585
			}
586

  
587
			if (!rounded) {
588
				d %= YEAR;
589
				mod = d % DAY;
590

  
591
				if (mod >= upperCeiling(DAY)) {
592
					if (prependBlank) {
593
						a.append(' ');
594
					}
595
					a.append(ceil(d, DAY));
596
					a.append(' ');
597
					a.append('d');
598
					++parts;
599
					rounded = true;
600
					prependBlank = true;
601
				} else if (d >= DAY) {
602
					if (prependBlank) {
603
						a.append(' ');
604
					}
605
					a.append(floor(d, DAY));
606
					a.append(' ');
607
					a.append('d');
608
					++parts;
609
					rounded = mod <= lowerCeiling(DAY);
610
					prependBlank = true;
611
				}
612

  
613
				if (parts < 2) {
614
					d %= DAY;
615
					mod = d % HOUR;
616

  
617
					if (mod >= upperCeiling(HOUR)) {
618
						if (prependBlank) {
619
							a.append(' ');
620
						}
621
						a.append(ceil(d, HOUR));
622
						a.append(' ');
623
						a.append('h');
624
						++parts;
625
						rounded = true;
626
						prependBlank = true;
627
					} else if (d >= HOUR && !rounded) {
628
						if (prependBlank) {
629
							a.append(' ');
630
						}
631
						a.append(floor(d, HOUR));
632
						a.append(' ');
633
						a.append('h');
634
						++parts;
635
						rounded = mod <= lowerCeiling(HOUR);
636
						prependBlank = true;
637
					}
638

  
639
					if (parts < 2) {
640
						d %= HOUR;
641
						mod = d % MINUTE;
642

  
643
						if (mod >= upperCeiling(MINUTE)) {
644
							if (prependBlank) {
645
								a.append(' ');
646
							}
647
							a.append(ceil(d, MINUTE));
648
							a.append(' ');
649
							a.append('m');
650
							++parts;
651
							rounded = true;
652
							prependBlank = true;
653
						} else if (d >= MINUTE && !rounded) {
654
							if (prependBlank) {
655
								a.append(' ');
656
							}
657
							a.append(floor(d, MINUTE));
658
							a.append(' ');
659
							a.append('m');
660
							++parts;
661
							rounded = mod <= lowerCeiling(MINUTE);
662
							prependBlank = true;
663
						}
664

  
665
						if (parts < 2) {
666
							d %= MINUTE;
667
							mod = d % SECOND;
668

  
669
							if (mod >= upperCeiling(SECOND)) {
670
								if (prependBlank) {
671
									a.append(' ');
672
								}
673
								a.append(ceil(d, SECOND));
674
								a.append(' ');
675
								a.append('s');
676
								++parts;
677
								rounded = true;
678
								prependBlank = true;
679
							} else if (d >= SECOND && !rounded) {
680
								if (prependBlank) {
681
									a.append(' ');
682
								}
683
								a.append(floor(d, SECOND));
684
								a.append(' ');
685
								a.append('s');
686
								++parts;
687
								rounded = mod <= lowerCeiling(SECOND);
688
								prependBlank = true;
689
							}
690

  
691
							if (parts < 2) {
692
								d %= SECOND;
693

  
694
								if (d > 0 && !rounded) {
695
									if (prependBlank) {
696
										a.append(' ');
697
									}
698
									a.append(Integer.toString((int) d));
699
									a.append(' ');
700
									a.append('m');
701
									a.append('s');
702
								}
703
							}
704

  
705
						}
706

  
707
					}
708

  
709
				}
710
			}
711
		} catch (IOException ex) {
712
			// What were they thinking...
713
		}
714

  
715
		return a;
716
	}
717

  
718
	/**
719
	 * Returns the time delta.
720
	 * 
721
	 * @return the time delta
722
	 */
723
	public long getDelta() {
724
		return delta;
725
	}
726

  
727
	/**
728
	 * @see java.lang.Object#equals(java.lang.Object)
729
	 */
730
	@Override
731
	public boolean equals(Object obj) {
732
		if (this == obj) {
733
			return true;
734
		}
735
		if (!(obj instanceof HumanTime)) {
736
			return false;
737
		}
738
		return delta == ((HumanTime) obj).delta;
739
	}
740

  
741
	/**
742
	 * Returns a 32-bit representation of the time delta.
743
	 * 
744
	 * @see java.lang.Object#hashCode()
745
	 */
746
	@Override
747
	public int hashCode() {
748
		return (int) (delta ^ (delta >> 32));
749
	}
750

  
751
	/**
752
	 * Returns a String representation of this.
753
	 * <p>
754
	 * The output is identical to {@link #getExactly()}.
755
	 * 
756
	 * @see java.lang.Object#toString()
757
	 * @see #getExactly()
758
	 * @return a String, never <code>null</code>
759
	 */
760
	@Override
761
	public String toString() {
762
		return getExactly();
763
	}
764

  
765
	/**
766
	 * Compares this HumanTime to another HumanTime.
767
	 * 
768
	 * @param t
769
	 *            the other instance, may not be <code>null</code>
770
	 * @return which one is greater
771
	 */
772
	@Override
773
	public int compareTo(HumanTime t) {
774
		return delta == t.delta ? 0 : (delta < t.delta ? -1 : 1);
775
	}
776

  
777
	/**
778
	 * Deep-clones this object.
779
	 * 
780
	 * @see java.lang.Object#clone()
781
	 * @throws CloneNotSupportedException
782
	 */
783
	@Override
784
	public Object clone() throws CloneNotSupportedException {
785
		return super.clone();
786
	}
787

  
788
	/**
789
	 * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
790
	 */
791
	@Override
792
	public void readExternal(ObjectInput in) throws IOException {
793
		delta = in.readLong();
794
	}
795

  
796
	/**
797
	 * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
798
	 */
799
	@Override
800
	public void writeExternal(ObjectOutput out) throws IOException {
801
		out.writeLong(delta);
802
	}
803

  
804
}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/iterators/xml/IterableXmlParser.java
1
package eu.dnetlib.miscutils.iterators.xml;
2

  
3
import java.io.ByteArrayInputStream;
4
import java.io.InputStream;
5
import java.nio.charset.Charset;
6
import java.util.Iterator;
7

  
8
public class IterableXmlParser implements Iterable<String> {
9

  
10
	private String element;
11

  
12
	private InputStream inputStream;
13

  
14
	public IterableXmlParser(String element, InputStream inputStream) {
15
		this.element = element;
16
		this.inputStream = inputStream;
17
	}
18

  
19
	public IterableXmlParser(String element, String xml) {
20
		this.element = element;
21
		this.inputStream = new ByteArrayInputStream(xml.getBytes(Charset.forName(XMLIterator.UTF_8)));
22
	}
23

  
24
	@Override
25
	public Iterator<String> iterator() {
26
		return new XMLIterator(element, inputStream);
27
	}
28

  
29
}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/iterators/xml/XMLIterator.java
1
package eu.dnetlib.miscutils.iterators.xml;
2

  
3
import java.io.InputStream;
4
import java.io.InputStreamReader;
5
import java.io.Reader;
6
import java.io.StringWriter;
7
import java.nio.charset.Charset;
8
import java.nio.charset.CharsetDecoder;
9
import java.nio.charset.CodingErrorAction;
10
import java.util.Iterator;
11

  
12
import javax.xml.stream.XMLEventFactory;
13
import javax.xml.stream.XMLEventReader;
14
import javax.xml.stream.XMLEventWriter;
15
import javax.xml.stream.XMLInputFactory;
16
import javax.xml.stream.XMLOutputFactory;
17
import javax.xml.stream.XMLStreamException;
18
import javax.xml.stream.events.StartElement;
19
import javax.xml.stream.events.XMLEvent;
20

  
21
import org.apache.commons.logging.Log;
22
import org.apache.commons.logging.LogFactory;
23

  
24
public class XMLIterator implements Iterator<String> {
25

  
26
	private static final Log log = LogFactory.getLog(XMLIterator.class);
27

  
28
	private ThreadLocal<XMLInputFactory> inputFactory = new ThreadLocal<XMLInputFactory>() {
29

  
30
		@Override
31
		protected XMLInputFactory initialValue() {
32
			return XMLInputFactory.newInstance();
33
		}
34
	};
35

  
36
	private ThreadLocal<XMLOutputFactory> outputFactory = new ThreadLocal<XMLOutputFactory>() {
37

  
38
		@Override
39
		protected XMLOutputFactory initialValue() {
40
			return XMLOutputFactory.newInstance();
41
		}
42
	};
43

  
44
	private ThreadLocal<XMLEventFactory> eventFactory = new ThreadLocal<XMLEventFactory>() {
45

  
46
		@Override
47
		protected XMLEventFactory initialValue() {
48
			return XMLEventFactory.newInstance();
49
		}
50
	};
51

  
52
	public static final String UTF_8 = "UTF-8";
53

  
54
	final XMLEventReader parser;
55

  
56
	private XMLEvent current = null;
57

  
58
	private String element;
59

  
60
	private InputStream inputStream;
61

  
62
	public XMLIterator(final String element, final InputStream inputStream) {
63
		super();
64
		this.element = element;
65
		this.inputStream = inputStream;
66
		this.parser = getParser();
67
		try {
68
			this.current = findElement(parser);
69
		} catch (XMLStreamException e) {
70
			log.warn("cannot init parser position. No element found: " + element);
71
			current = null;
72
		}
73
	}
74

  
75
	@Override
76
	public boolean hasNext() {
77
		return current != null;
78
	}
79

  
80
	@Override
81
	public String next() {
82
		String result = null;
83
		try {
84
			result = copy(parser);
85
			current = findElement(parser);
86
			return result;
87
		} catch (XMLStreamException e) {
88
			throw new RuntimeException(String.format("error copying xml, built so far: '%s'", result), e);
89
		}
90
	}
91

  
92
	@Override
93
	public void remove() {
94
		throw new UnsupportedOperationException();
95
	}
96

  
97
	@SuppressWarnings("finally")
98
	private String copy(final XMLEventReader parser) throws XMLStreamException {
99
		final StringWriter result = new StringWriter();
100
		try {
101
			final XMLEventWriter writer = outputFactory.get().createXMLEventWriter(result);
102
			final StartElement start = current.asStartElement();
103
			final StartElement newRecord = eventFactory.get().createStartElement(start.getName(), start.getAttributes(), start.getNamespaces());
104

  
105
			// new root record
106
			writer.add(newRecord);
107

  
108
			// copy the rest as it is
109
			while (parser.hasNext()) {
110
				final XMLEvent event = parser.nextEvent();
111

  
112
				// TODO: replace with depth tracking instead of close tag tracking.
113
				if (event.isEndElement() && event.asEndElement().getName().getLocalPart().equals(element)) {
114
					writer.add(event);
115
					break;
116
				}
117

  
118
				writer.add(event);
119
			}
120
			writer.close();
121
		} finally {
122
			return result.toString();
123
		}
124
	}
125

  
126
	/**
127
	 * Looks for the next occurrence of the splitter element.
128
	 *
129
	 * @param parser
130
	 * @return
131
	 * @throws XMLStreamException
132
	 */
133
	private XMLEvent findElement(final XMLEventReader parser) throws XMLStreamException {
134

  
135
		/*
136
		 * if (current != null && element.equals(current.asStartElement().getName().getLocalPart())) { return current; }
137
		 */
138

  
139
		XMLEvent peek = parser.peek();
140
		if (peek != null && peek.isStartElement()) {
141
			String name = peek.asStartElement().getName().getLocalPart();
142
			if (element.equals(name)) { return peek; }
143
		}
144

  
145
		while (parser.hasNext()) {
146
			final XMLEvent event = parser.nextEvent();
147
			if (event != null && event.isStartElement()) {
148
				String name = event.asStartElement().getName().getLocalPart();
149
				if (element.equals(name)) { return event; }
150
			}
151
		}
152
		return null;
153
	}
154

  
155
	private XMLEventReader getParser() {
156
		try {
157
			return inputFactory.get().createXMLEventReader(sanitize(inputStream));
158
		} catch (XMLStreamException e) {
159
			throw new RuntimeException(e);
160
		}
161
	}
162

  
163
	private Reader sanitize(final InputStream in) {
164
		final CharsetDecoder charsetDecoder = Charset.forName(UTF_8).newDecoder();
165
		charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE);
166
		charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
167
		return new InputStreamReader(in, charsetDecoder);
168
	}
169

  
170
}
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/iterators/IterableIterator.java
1
package eu.dnetlib.miscutils.iterators;
2

  
3
import java.util.Iterator;
4

  
5
/**
6
 * Useful if you want to quickly iterate an iterable with the new java 5 syntax.
7
 *
8
 * @author marko
9
 *
10
 * @param <T>
11
 */
12
public class IterableIterator<T> implements Iterable<T> {
13
        private Iterator<T> iter;
14

  
15
        public IterableIterator(Iterator<T> iter) {
16
                this.iter = iter;
17
        }
18

  
19
        @Override
20
		public Iterator<T> iterator() {
21
                return iter;
22
        }
23
}
24

  
modules/cnr-misc-utils/tags/cnr-misc-utils-1.0.4/src/main/java/eu/dnetlib/miscutils/iterators/IterablePair.java
1
package eu.dnetlib.miscutils.iterators;
2

  
3
import java.util.Iterator;
4
import java.util.List;
5

  
6
import eu.dnetlib.miscutils.collections.Pair;
7

  
8
public class IterablePair <A, B> implements Iterable<Pair<A, B>> {
9
    private final List<A> first;
10
    private final List<B> second;
11

  
12
    public IterablePair(List<A> first, List<B> second) { 
13
        this.first = first;
14
        this.second = second;
15
    }
16

  
17
    @Override
18
    public Iterator<Pair<A, B>> iterator() {
19
        return new ParallelIterator<A, B>(first.iterator(), second.iterator());
20
    }
21
}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff