locationutils.java

来自「在Struts2中的jar包xwork的源代码.版本为2.0.7」· Java 代码 · 共 309 行

JAVA
309
字号
/* * Copyright 2005 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.opensymphony.xwork2.util.location;import java.lang.ref.WeakReference;import java.net.URL;import java.util.ArrayList;import java.util.List;import javax.xml.transform.SourceLocator;import javax.xml.transform.TransformerException;import org.xml.sax.Locator;import org.xml.sax.SAXParseException;import org.w3c.dom.Element;import com.opensymphony.xwork2.util.ClassLoaderUtil;/** * Location-related utility methods. */public class LocationUtils {        /**     * The string representation of an unknown location: "<code>[unknown location]</code>".     */    public static final String UNKNOWN_STRING = "[unknown location]";        private static List finders = new ArrayList();        /**     * An finder or object locations     */    public interface LocationFinder {        /**         * Get the location of an object         * @param obj the object for which to find a location         * @param description and optional description to be added to the object's location         * @return the object's location or <code>null</code> if object's class isn't handled         *         by this finder.         */        Location getLocation(Object obj, String description);    }    private LocationUtils() {        // Forbid instanciation    }        /**     * Builds a string representation of a location, in the     * "<code><em>descripton</em> - <em>uri</em>:<em>line</em>:<em>column</em></code>"     * format (e.g. "<code>foo - file://path/to/file.xml:3:40</code>"). For {@link Location#UNKNOWN an unknown location}, returns     * {@link #UNKNOWN_STRING}.     *      * @return the string representation     */    public static String toString(Location location) {        StringBuffer result = new StringBuffer();        String description = location.getDescription();        if (description != null) {            result.append(description).append(" - ");        }        String uri = location.getURI();        if (uri != null) {            result.append(uri).append(':').append(location.getLineNumber()).append(':').append(location.getColumnNumber());        } else {            result.append(UNKNOWN_STRING);        }                return result.toString();    }    /**     * Parse a location string of the form "<code><em>uri</em>:<em>line</em>:<em>column</em></code>" (e.g.     * "<code>path/to/file.xml:3:40</code>") to a Location object. Additionally, a description may     * also optionally be present, separated with an hyphen (e.g. "<code>foo - path/to/file.xml:3.40</code>").     *      * @param text the text to parse     * @return the location (possibly <code>null</code> if text was null or in an incorrect format)     */    public static LocationImpl parse(String text) throws IllegalArgumentException {        if (text == null || text.length() == 0) {            return null;        }        // Do we have a description?        String description;        int uriStart = text.lastIndexOf(" - "); // lastIndexOf to allow the separator to be in the description        if (uriStart > -1) {            description = text.substring(0, uriStart);            uriStart += 3; // strip " - "        } else {            description = null;            uriStart = 0;        }                try {            int colSep = text.lastIndexOf(':');            if (colSep > -1) {                int column = Integer.parseInt(text.substring(colSep + 1));                                int lineSep = text.lastIndexOf(':', colSep - 1);                if (lineSep > -1) {                    int line = Integer.parseInt(text.substring(lineSep + 1, colSep));                    return new LocationImpl(description, text.substring(uriStart, lineSep), line, column);                }            } else {                // unkonwn?                if (text.endsWith(UNKNOWN_STRING)) {                    return LocationImpl.UNKNOWN;                }            }        } catch(Exception e) {            // Ignore: handled below        }                return LocationImpl.UNKNOWN;    }    /**     * Checks if a location is known, i.e. it is not null nor equal to {@link Location#UNKNOWN}.     *      * @param location the location to check     * @return <code>true</code> if the location is known     */    public static boolean isKnown(Location location) {        return location != null && !Location.UNKNOWN.equals(location);    }    /**     * Checks if a location is unknown, i.e. it is either null or equal to {@link Location#UNKNOWN}.     *      * @param location the location to check     * @return <code>true</code> if the location is unknown     */    public static boolean isUnknown(Location location) {        return location == null || Location.UNKNOWN.equals(location);    }    /**     * Add a {@link LocationFinder} to the list of finders that will be queried for an object's     * location by {@link #getLocation(Object, String)}.     * <p>     * <b>Important:</b> LocationUtils internally stores a weak reference to the finder. This     * avoids creating strong links between the classloader holding this class and the finder's     * classloader, which can cause some weird memory leaks if the finder's classloader is to     * be reloaded. Therefore, you <em>have</em> to keep a strong reference to the finder in the     * calling code, e.g.:     * <pre>     *   private static LocationUtils.LocationFinder myFinder =     *       new LocationUtils.LocationFinder() {     *           public Location getLocation(Object obj, String desc) {     *               ...     *           }     *       };     *     *   static {     *       LocationUtils.addFinder(myFinder);     *   }     * </pre>     *      * @param finder the location finder to add     */    public static void addFinder(LocationFinder finder) {        if (finder == null) {            return;        }        synchronized(LocationFinder.class) {            // Update a clone of the current finder list to avoid breaking            // any iteration occuring in another thread.            List newFinders = new ArrayList(finders);            newFinders.add(new WeakReference(finder));            finders = newFinders;        }    }        /**     * Get the location of an object. Some well-known located classes built in the JDK are handled     * by this method. Handling of other located classes can be handled by adding new location finders.     *      * @param obj the object of which to get the location     * @return the object's location, or {@link Location#UNKNOWN} if no location could be found     */    public static Location getLocation(Object obj) {        return getLocation(obj, null);    }        /**     * Get the location of an object. Some well-known located classes built in the JDK are handled     * by this method. Handling of other located classes can be handled by adding new location finders.     *      * @param obj the object of which to get the location     * @param description an optional description of the object's location, used if a Location object     *        has to be created.     * @return the object's location, or {@link Location#UNKNOWN} if no location could be found     */    public static Location getLocation(Object obj, String description) {        if (obj instanceof Location) {            return (Location) obj;        }                if (obj instanceof Locatable) {            return ((Locatable)obj).getLocation();        }                // Check some well-known locatable exceptions        if (obj instanceof SAXParseException) {            SAXParseException spe = (SAXParseException)obj;            if (spe.getSystemId() != null) {                return new LocationImpl(description, spe.getSystemId(), spe.getLineNumber(), spe.getColumnNumber());            } else {                return Location.UNKNOWN;            }        }                if (obj instanceof TransformerException) {            TransformerException ex = (TransformerException)obj;            SourceLocator locator = ex.getLocator();            if (locator != null && locator.getSystemId() != null) {                return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());            } else {                return Location.UNKNOWN;            }        }                if (obj instanceof Locator) {            Locator locator = (Locator)obj;            if (locator.getSystemId() != null) {                return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());            } else {                return Location.UNKNOWN;            }        }                if (obj instanceof Element) {            return LocationAttributes.getLocation((Element)obj);        }        List currentFinders = finders; // Keep the current list        int size = currentFinders.size();        for (int i = 0; i < size; i++) {            WeakReference ref = (WeakReference)currentFinders.get(i);            LocationFinder finder = (LocationFinder)ref.get();            if (finder == null) {                // This finder was garbage collected: update finders                synchronized(LocationFinder.class) {                    // Update a clone of the current list to avoid breaking current iterations                    List newFinders = new ArrayList(finders);                    newFinders.remove(ref);                    finders = newFinders;                }            }                        Location result = finder.getLocation(obj, description);            if (result != null) {                return result;            }        }                if (obj instanceof Throwable) {        		Throwable t = (Throwable) obj;        		StackTraceElement[] stack = t.getStackTrace();        		if (stack != null && stack.length > 0) {        			StackTraceElement trace = stack[0];        			if (trace.getLineNumber() >= 0) {	        			String uri = trace.getClassName();	        			if (trace.getFileName() != null) {	        				uri = uri.replace('.','/');	        				uri = uri.substring(0, uri.lastIndexOf('/') + 1);	        				uri = uri + trace.getFileName();	        				URL url = ClassLoaderUtil.getResource(uri, LocationUtils.class);	        				if (url != null) {        						uri = url.toString();	        				}	        			}	        			if (description == null) {	        				StringBuilder sb = new StringBuilder();	        				sb.append("Class: ").append(trace.getClassName()).append("\n");	        				sb.append("File: ").append(trace.getFileName()).append("\n");	        				sb.append("Method: ").append(trace.getMethodName()).append("\n");	        				sb.append("Line: ").append(trace.getLineNumber());	        				description = sb.toString();	        			}	        			return new LocationImpl(description, uri, trace.getLineNumber(), -1);        			}        		}        }        return Location.UNKNOWN;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?