Class Debug

  1  
  2  
  3 /*
  4  * Copyright (c) 2016 Vivid Solutions.
  5  *
  6  * All rights reserved. This program and the accompanying materials
  7  * are made available under the terms of the Eclipse Public License 2.0
  8  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
  9  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
 10  * and the Eclipse Distribution License is available at
 11  *
 12  * http://www.eclipse.org/org/documents/edl-v10.php.
 13  */
 14 package org.locationtech.jts.util;
 15  
 16 /**
 17  *@version 1.7
 18  */
 19 import java.io.PrintStream;
 20 import java.lang.reflect.Method;
 21 import java.util.Collection;
 22 import java.util.Iterator;
 23  
 24 import org.locationtech.jts.geom.Coordinate;
 25 import org.locationtech.jts.geom.CoordinateSequence;
 26 import org.locationtech.jts.geom.CoordinateSequenceFilter;
 27 import org.locationtech.jts.geom.Geometry;
 28 import org.locationtech.jts.geom.GeometryFactory;
 29 import org.locationtech.jts.geom.LineString;
 30  
 31 /**
 32  * Provides routines to simplify and localize debugging output.
 33  * Debugging is controlled via a Java system property value.
 34  * If the system property with the name given in
 35  * DEBUG_PROPERTY_NAME (currently "jts.debug") has the value
 36  * "on" or "true" debugging is enabled.
 37  * Otherwise, debugging is disabled.
 38  * The system property can be set by specifying the following JVM option:
 39  * <pre>
 40  * -Djts.debug=on
 41  * </pre>
 42  * 
 43  *
 44  * @version 1.7
 45  */
 46 public class Debug {
 47  
 48   public static String DEBUG_PROPERTY_NAME = "jts.debug";
 49   public static String DEBUG_PROPERTY_VALUE_ON = "on";
 50   public static String DEBUG_PROPERTY_VALUE_TRUE = "true";
 51  
 52   private static boolean debugOn = false;
 53  
 54   static {
 55     String debugValue = System.getProperty(DEBUG_PROPERTY_NAME);
 56     if (debugValue != null) {
 57       if (debugValue.equalsIgnoreCase(DEBUG_PROPERTY_VALUE_ON)
 58           || debugValue.equalsIgnoreCase(DEBUG_PROPERTY_VALUE_TRUE) )
 59         debugOn = true;
 60     }
 61   }
 62  
 63   private static Stopwatch stopwatch = new Stopwatch();
 64   private static long lastTimePrinted;
 65  
 66   /**
 67    * Prints the status of debugging to <tt>System.out</tt>
 68    *
 69    * @param args the cmd-line arguments (no arguments are required)
 70    */
 71   public static void main(String[] args)
 72   {
 73     System.out.println("JTS Debugging is " +
 74                        (debugOn ? "ON" : "OFF") );
 75   }
 76  
 77   private static final Debug debug = new Debug();
 78   private static final GeometryFactory fact = new GeometryFactory();
 79   private static final String DEBUG_LINE_TAG = "D! ";
 80  
 81   private PrintStream out;
 82   private Class[] printArgs;
 83   private Object watchObj = null;
 84   private Object[] args = new Object[1];
 85  
 86   public static boolean isDebugging() { return debugOn; }
 87  
 88   public static LineString toLine(Coordinate p0, Coordinate p1) {
 89     return fact.createLineString(new Coordinate[] { p0, p1 });
 90   }
 91  
 92   public static LineString toLine(Coordinate p0, Coordinate p1, Coordinate p2) {
 93     return fact.createLineString(new Coordinate[] { p0, p1, p2});
 94   }
 95  
 96   public static LineString toLine(Coordinate p0, Coordinate p1, Coordinate p2, Coordinate p3) {
 97     return fact.createLineString(new Coordinate[] { p0, p1, p2, p3});
 98   }
 99  
100   public static void print(String str) {
101     if (!debugOn) {
102       return;
103     }
104     debug.instancePrint(str);
105   }
106 /*
107   public static void println(String str) {
108     if (! debugOn) return;
109     debug.instancePrint(str);
110     debug.println();
111   }
112 */
113   public static void print(Object obj) {
114     if (! debugOn) return;
115     debug.instancePrint(obj);
116   }
117  
118   public static void print(boolean isTrue, Object obj) {
119     if (! debugOn) return;
120     if (! isTrue) return;
121     debug.instancePrint(obj);
122   }
123  
124   public static void println(Object obj) {
125     if (!debugOn) {
126       return;
127     }
128     debug.instancePrint(obj);
129     debug.println();
130   }
131   
132   public static void resetTime()
133   {
134     stopwatch.reset();
135     lastTimePrinted = stopwatch.getTime();
136   }
137   
138   public static void printTime(String tag)
139   {
140     if (!debugOn) {
141       return;
142     }
143     long time = stopwatch.getTime();
144     long elapsedTime = time - lastTimePrinted;
145     debug.instancePrint(
146         formatField(Stopwatch.getTimeString(time), 10)
147         + " (" + formatField(Stopwatch.getTimeString(elapsedTime), 10) + " ) "
148         + tag);
149     debug.println();    
150     lastTimePrinted = time;
151   }
152   
153   private static String formatField(String s, int fieldLen)
154   {
155     int nPad = fieldLen - s.length();
156     if (nPad <= 0return s;
157     String padStr = spaces(nPad) + s;
158     return padStr.substring(padStr.length() - fieldLen);
159   }
160   
161   private static String spaces(int n)
162   {
163     char[] ch = new char[n];
164     for (int i = 0; i < n; i++) {
165       ch[i] = ' ';
166     }
167     return new String(ch);
168   }
169   
170   public static boolean equals(Coordinate c1, Coordinate c2, double tolerance)
171   {
172       return c1.distance(c2) <= tolerance;
173   }
174   /**
175    * Adds an object to be watched.
176    * A watched object can be printed out at any time.
177    * 
178    * Currently only supports one watched object at a time.
179    * @param obj
180    */
181   public static void addWatch(Object obj) {
182     debug.instanceAddWatch(obj);
183   }
184  
185   public static void printWatch() {
186     debug.instancePrintWatch();
187   }
188  
189   public static void printIfWatch(Object obj) {
190     debug.instancePrintIfWatch(obj);
191   }
192  
193   public static void breakIf(boolean cond)
194   {
195     if (cond) doBreak();
196   }
197   
198   public static void breakIfEqual(Object o1, Object o2)
199   {
200     if (o1.equals(o2)) doBreak();
201   }
202   
203   public static void breakIfEqual(Coordinate p0, Coordinate p1, double tolerance)
204   {
205     if (p0.distance(p1) <= tolerance) doBreak();
206   }
207   
208   private static void doBreak()
209   {
210     // Put breakpoint on following statement to break here
211     return
212   }
213   
214   public static boolean hasSegment(Geometry geom, Coordinate p0, Coordinate p1)
215   {
216     SegmentFindingFilter filter = new SegmentFindingFilter(p0, p1);
217     geom.apply(filter);
218     return filter.hasSegment();
219   }
220   
221   private static class SegmentFindingFilter
222   implements CoordinateSequenceFilter
223   {
224     private Coordinate p0p1;
225     private boolean hasSegment = false;
226     
227     public SegmentFindingFilter(Coordinate p0, Coordinate p1)
228     {
229       this.p0 = p0;
230       this.p1 = p1;
231     }
232  
233     public boolean hasSegment() { return hasSegment; }
234  
235     public void filter(CoordinateSequence seq, int i)
236     {
237       if (i == 0return;
238       hasSegment = p0.equals2D(seq.getCoordinate(i-1)) 
239           && p1.equals2D(seq.getCoordinate(i));
240     }
241     
242     public boolean isDone()
243     {
244       return hasSegment; 
245     }
246     
247     public boolean isGeometryChanged()
248     {
249       return false;
250     }
251   }
252   
253   private Debug() {
254     out = System.out;
255     printArgs = new Class[1];
256     try {
257       printArgs[0] = Class.forName("java.io.PrintStream");
258     }
259     catch (Exception ex) {
260       // ignore this exception - it will fail later anyway
261     }
262   }
263  
264   public void instancePrintWatch() {
265     if (watchObj == nullreturn;
266     instancePrint(watchObj);
267   }
268  
269   public void instancePrintIfWatch(Object obj) {
270     if (obj != watchObj) return;
271     if (watchObj == nullreturn;
272     instancePrint(watchObj);
273   }
274  
275   public void instancePrint(Object obj)
276   {
277     if (obj instanceof Collection) {
278       instancePrint(((Collection) obj).iterator());
279     }
280     else if (obj instanceof Iterator) {
281       instancePrint((Iterator) obj);
282     }
283     else {
284       instancePrintObject(obj);
285     }
286   }
287  
288   public void instancePrint(Iterator it)
289   {
290     for (; it.hasNext(); ) {
291       Object obj = it.next();
292       instancePrintObject(obj);
293     }
294   }
295   public void instancePrintObject(Object obj) {
296     //if (true) throw new RuntimeException("DEBUG TRAP!");
297     Method printMethod = null;
298     try {
299       Class cls = obj.getClass();
300       try {
301         printMethod = cls.getMethod("print", printArgs);
302         args[0] = out;
303         out.print(DEBUG_LINE_TAG);
304         printMethod.invoke(obj, args);
305       }
306       catch (NoSuchMethodException ex) {
307         instancePrint(obj.toString());
308       }
309     }
310     catch (Exception ex) {
311       ex.printStackTrace(out);
312     }
313   }
314  
315   public void println() {
316     out.println();
317   }
318  
319   private void instanceAddWatch(Object obj) {
320     watchObj = obj;
321   }
322  
323   private void instancePrint(String str) {
324     out.print(DEBUG_LINE_TAG);
325     out.print(str);
326   }
327  
328 }
329