alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Struts example source code file (LocationUtils.java)

This example Struts source code file (LocationUtils.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Struts tags/keywords

arraylist, dom, list, list, location, location, locationimpl, locationimpl, locator, net, network, sax, saxparseexception, string, string, stringbuilder, throwable, transformerexception, util

The Struts LocationUtils.java source code

/*
 * 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 com.opensymphony.xwork2.util.ClassLoaderUtil;
import org.w3c.dom.Element;
import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;

import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * Location-related utility methods.
 */
public class LocationUtils {
    
    /**
     * The string representation of an unknown location: "<code>[unknown location]".
     */
    public static final String UNKNOWN_STRING = "[unknown location]";
    
    private static List<WeakReference 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 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>descripton - uri:line:column"
     * format (e.g. "<code>foo - file://path/to/file.xml:3:40"). For {@link Location#UNKNOWN an unknown location}, returns
     * {@link #UNKNOWN_STRING}.
     * 
     * @return the string representation
     */
    public static String toString(Location location) {
        StringBuilder result = new StringBuilder();

        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>uri:line:column" (e.g.
     * "<code>path/to/file.xml:3:40") 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").
     * 
     * @param text the text to parse
     * @return the location (possibly <code>null 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 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 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: 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 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<WeakReference newFinders = new ArrayList>(finders);
            newFinders.add(new WeakReference<LocationFinder>(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<WeakReference currentFinders = finders; // Keep the current list
        int size = currentFinders.size();
        for (int i = 0; i < size; i++) {
            WeakReference<LocationFinder> ref = currentFinders.get(i);
            LocationFinder finder = 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<WeakReference 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;
    }
}

Other Struts examples (source code examples)

Here is a short list of links related to this Struts LocationUtils.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.