/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.propertyeditor;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;

import org.jboss.logging.Logger;
import org.jboss.util.Classes;

/**
 * A collection of PropertyEditor utilities. Provides the same interface
 * as PropertyEditorManager plus more...
 *
 *
Installs the default PropertyEditors.
 *
 * @author  Jason Dillon
 * @author  Scott Stark
 * @version <tt>$Revision$</tt>
 */
@SuppressWarnings("unchecked")
public class PropertyEditors
{
   /** The Logger object */
   private static Logger log = Logger.getLogger(PropertyEditors.class);

   /** The null string */
   private static final String NULL = "null";

   /** Whether we handle nulls */
   private static boolean disableIsNull = false;

   /** Whether or not initialization of the editor search path has been done */
   private static boolean initialized = false;

   static
   {
      init();
   }

   /**
    * Augment the PropertyEditorManager search path to incorporate the JBoss
    * specific editors by appending the org.jboss.util.propertyeditor package
    * to the PropertyEditorManager editor search path.
    */
   public synchronized static void init()
   {
      if( initialized == false )
      {
         AccessController.doPrivileged(Initialize.instance);
         initialized = true;
      }
   }

   /**
    * Whether a string is interpreted as the null value,
    * including the empty string.
    *
    * @param value the value
    * @return true when the string has the value null
    */
   public static final boolean isNull(final String value)
   {
      return isNull(value, true, true);
   }

   /**
    * Whether a string is interpreted as the null value
    *
    * @param value the value
    * @param trim whether to trim the string
    * @param empty whether to include the empty string as null
    * @return true when the string has the value null
    */
   public static final boolean isNull(final String value, final boolean trim, final boolean empty)
   {
      // For backwards compatibility
      if (disableIsNull)
         return false;
      // No value?
      if (value == null)
         return true;
      // Trim the text when requested
      String trimmed = trim ? value.trim() : value;
      // Is the empty string null?
      if (empty && trimmed.length() == 0)
         return true;
      // Just check it.
      return NULL.equalsIgnoreCase(trimmed);
   }

   /**
    * Will the standard editors return null from their
    * {@link PropertyEditor#setAsText(String)} method for non-primitive targets?
    *
    * @return True if nulls can be returned; false otherwise.
    */
   public static boolean isNullHandlingEnabled()
   {
      return !disableIsNull;
   }

   /**
    * Locate a value editor for a given target type.
    *
    * @param type   The class of the object to be edited.
    * @return       An editor for the given type or null if none was found.
    */
   public static PropertyEditor findEditor(final Class<?> type)
   {
      return PropertyEditorManager.findEditor(type);
   }

   /**
    * Locate a value editor for a given target type.
    *
    * @param typeName    The class name of the object to be edited.
    * @return            An editor for the given type or null if none was found.
    * @throws ClassNotFoundException when the class could not be found
    */
   public static PropertyEditor findEditor(final String typeName)
      throws ClassNotFoundException
   {
      // see if it is a primitive type first
      Class<?> type = Classes.getPrimitiveTypeForName(typeName);
      if (type == null)
      {
         // nope try look up
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
         type = loader.loadClass(typeName);
      }

      return PropertyEditorManager.findEditor(type);
   }

   /**
    * Get a value editor for a given target type.
    *
    * @param type    The class of the object to be edited.
    * @return        An editor for the given type.
    *
    * @throws RuntimeException   No editor was found.
    */
   public static PropertyEditor getEditor(final Class<?> type)
   {
      PropertyEditor editor = findEditor(type);
      if (editor == null)
      {
         throw new RuntimeException("No property editor for type: " + type);
      }

      return editor;
   }

   /**
    * Get a value editor for a given target type.
    *
    * @param typeName    The class name of the object to be edited.
    * @return            An editor for the given type.
    *
    * @throws RuntimeException   No editor was found.
    * @throws ClassNotFoundException when the class is not found
    */
   public static PropertyEditor getEditor(final String typeName)
      throws ClassNotFoundException
   {
      PropertyEditor editor = findEditor(typeName);
      if (editor == null)
      {
         throw new RuntimeException("No property editor for type: " + typeName);
      }

      return editor;
   }

   /**
    * Register an editor class to be used to editor values of a given target class.
    *
    * @param type         The class of the objetcs to be edited.
    * @param editorType   The class of the editor.
    */
   public static void registerEditor(final Class<?> type, final Class<?> editorType)
   {
      PropertyEditorManager.registerEditor(type, editorType);
   }

   /**
    * Register an editor class to be used to editor values of a given target class.
    *
    * @param typeName         The classname of the objetcs to be edited.
    * @param editorTypeName   The class of the editor.
    * @throws ClassNotFoundException when the class could not be found
    */
   public static void registerEditor(final String typeName,
                                     final String editorTypeName)
      throws ClassNotFoundException
   {
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      Class<?> type = loader.loadClass(typeName);
      Class<?> editorType = loader.loadClass(editorTypeName);

      PropertyEditorManager.registerEditor(type, editorType);
   }

   /** Convert a string value into the true value for typeName using the
    * PropertyEditor associated with typeName.
    *
    * @param text the string represention of the value. This is passed to
    * the PropertyEditor.setAsText method.
    * @param typeName the fully qualified class name of the true value type
    * @return the PropertyEditor.getValue() result
    * @exception ClassNotFoundException thrown if the typeName class cannot
    *    be found
    * @exception IntrospectionException thrown if a PropertyEditor for typeName
    *    cannot be found
    */
   public static Object convertValue(String text, String typeName)
         throws ClassNotFoundException, IntrospectionException
   {
      // see if it is a primitive type first
      Class<?> typeClass = Classes.getPrimitiveTypeForName(typeName);
      if (typeClass == null)
      {
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
         typeClass = loader.loadClass(typeName);
      }

      PropertyEditor editor = PropertyEditorManager.findEditor(typeClass);
      if (editor == null)
      {
         throw new IntrospectionException
               ("No property editor for type=" + typeClass);
      }

      editor.setAsText(text);
      return editor.getValue();
   }

   /**
    * This method takes the properties found in the given beanProps
    * to the bean using the property editor registered for the property.
    * Any property in beanProps that does not have an associated java bean
    * property will result in an IntrospectionException. The string property
    * values are converted to the true java bean property type using the
    * java bean PropertyEditor framework. If a property in beanProps does not
    * have a PropertyEditor registered it will be ignored.
    *
    * @param bean - the java bean instance to apply the properties to
    * @param beanProps - map of java bean property name to property value.
    * @throws IntrospectionException thrown on introspection of bean and if
    *    a property in beanProps does not map to a property of bean.
    */
   public static void mapJavaBeanProperties(Object bean, Properties beanProps)
      throws IntrospectionException
   {
      mapJavaBeanProperties(bean, beanProps, true);
   }

   /**
    * This method takes the properties found in the given beanProps
    * to the bean using the property editor registered for the property.
    * Any property in beanProps that does not have an associated java bean
    * property will result in an IntrospectionException. The string property
    * values are converted to the true java bean property type using the
    * java bean PropertyEditor framework. If a property in beanProps does not
    * have a PropertyEditor registered it will be ignored.
    *
    * @param bean - the java bean instance to apply the properties to
    * @param beanProps - map of java bean property name to property value.
    * @param isStrict - indicates if should throw exception if bean property can not
    * be matched.  True for yes, false for no.
    * @throws IntrospectionException thrown on introspection of bean and if
    *    a property in beanProps does not map to a property of bean.
    */
   public static void mapJavaBeanProperties(Object bean, Properties beanProps, boolean isStrict)
      throws IntrospectionException
   {

      HashMap<String, PropertyDescriptor> propertyMap = new HashMap<String, PropertyDescriptor>();
      BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
      PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
      for (int p = 0; p < props.length; p++)
      {
         String fieldName = props[p].getName();
         propertyMap.put(fieldName, props[p]);
      }

      boolean trace = log.isTraceEnabled();
      Iterator keys = beanProps.keySet().iterator();
      if( trace )
         log.trace("Mapping properties for bean: "+bean);
      while( keys.hasNext() )
      {
         String name = (String) keys.next();
         String text = beanProps.getProperty(name);
         PropertyDescriptor pd = propertyMap.get(name);
         if (pd == null)
         {
            /* Try the property name with the first char uppercased to handle
            a property name like dLQMaxResent whose expected introspected
            property name would be DLQMaxResent since the JavaBean
            Introspector would view setDLQMaxResent as the setter for a
            DLQMaxResent property whose Introspector.decapitalize() method
            would also return "DLQMaxResent".
            */
            if (name.length() > 1)
            {
               char first = name.charAt(0);
               String exName = Character.toUpperCase(first) + name.substring(1);
               pd = propertyMap.get(exName);

               // Be lenient and check the other way around, e.g. ServerName -> serverName
               if (pd == null)
               {
                  exName = Character.toLowerCase(first) + name.substring(1);
                  pd = propertyMap.get(exName);
               }
            }

            if (pd == null)
            {
               if (isStrict)
               {
                  String msg = "No property found for: "+name+" on JavaBean: "+bean;
                  throw new IntrospectionException(msg);
               }
               else
               {
                  // since is not strict, ignore that this property was not found
                  continue;
               }
            }
         }
         Method setter = pd.getWriteMethod();
         if( trace )
            log.trace("Property editor found for: "+name+", editor: "+pd+", setter: "+setter);
         if (setter != null)
         {
            Class<?> ptype = pd.getPropertyType();
            PropertyEditor editor = PropertyEditorManager.findEditor(ptype);
            if (editor == null)
            {
               if( trace )
                  log.trace("Failed to find property editor for: "+name);
            }
            try
            {
               editor.setAsText(text);
               Object args[] = {editor.getValue()};
               setter.invoke(bean, args);
            }
            catch (Exception e)
            {
               if( trace )
                  log.trace("Failed to write property", e);
            }
         }
      }
   }

   /**
    * Gets the package names that will be searched for property editors.
    *
    * @return   The package names that will be searched for property editors.
    */
   public String[] getEditorSearchPath()
   {
      return PropertyEditorManager.getEditorSearchPath();
   }

   /**
    * Sets the package names that will be searched for property editors.
    *
    * @param path   The serach path.
    */
   public void setEditorSearchPath(final String[] path)
   {
      PropertyEditorManager.setEditorSearchPath(path);
   }

   private static class Initialize implements PrivilegedAction<Object>
   {
      static Initialize instance = new Initialize();

      public Object run()
      {
         String[] currentPath = PropertyEditorManager.getEditorSearchPath();
         int length = currentPath != null ? currentPath.length : 0;
         String[] newPath = new String[length+2];
         System.arraycopy(currentPath, 0, newPath, 2, length);
         // Put the JBoss editor path first
         // The default editors are not very flexible
         newPath[0] = "org.jboss.util.propertyeditor";
         newPath[1] = "org.jboss.mx.util.propertyeditor";
         PropertyEditorManager.setEditorSearchPath(newPath);

         /* Register the editor types that will not be found using the standard
         class name to editor name algorithm. For example, the type String[] has
         a name '[Ljava.lang.String;' which does not map to a XXXEditor name.
         */
         Class<?> strArrayType = String[].class;
         PropertyEditorManager.registerEditor(strArrayType, StringArrayEditor.class);
         Class<?> clsArrayType = Class[].class;
         PropertyEditorManager.registerEditor(clsArrayType, ClassArrayEditor.class);
         Class<?> intArrayType = int[].class;
         PropertyEditorManager.registerEditor(intArrayType, IntArrayEditor.class);
         Class<?> byteArrayType = byte[].class;
         PropertyEditorManager.registerEditor(byteArrayType, ByteArrayEditor.class);

         // There is no default char editor.
         PropertyEditorManager.registerEditor(Character.TYPE, CharacterEditor.class);

         try
         {
            if (System.getProperty("org.jboss.util.property.disablenull") != null)
               disableIsNull = true;
         }
         catch (Throwable ignored)
         {
            log.trace("Error retrieving system property org.jboss.util.property.diablenull", ignored);
         }
         return null;
      }
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.net.sockets;

import java.io.IOException;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.rmi.server.RMIServerSocketFactory;

/**
 * A RMIServerSocketFactory that installs a InterruptableInputStream to be
 * responsive to thead interruption events.
 *
 * @author Scott.Stark@jboss.org
 * @version $Revision$
 */
public class TimeoutServerSocketFactory
   implements RMIServerSocketFactory, Serializable
{
   /** @since 3.2.6 */
   static final long serialVersionUID = 7006964274840965634L;
   protected transient InetAddress bindAddress;
   protected int backlog = 200;

   /**
    * Create a socket factory that binds on any address with a default
    * backlog of 200
    */
   public TimeoutServerSocketFactory()
   {
      this(null, 200);
   }

   /**
    * Create a socket factory with the given bind address
    * @param bindAddress
    */
   public TimeoutServerSocketFactory(InetAddress bindAddress)
   {
      this(bindAddress, 200);
   }

   /**
    * Create a socket factory with the given backlog
    * @param backlog
    */
   public TimeoutServerSocketFactory(int backlog)
   {
      this(null, backlog);
   }

   /**
    * Create a socket factory with the given bind address and backlog
    * @param bindAddress
    * @param backlog
    */
   public TimeoutServerSocketFactory(InetAddress bindAddress, int backlog)
   {
      this.bindAddress = bindAddress;
      this.backlog = backlog;
   }

   public String getBindAddress()
   {
      String address = null;
      if (bindAddress != null)
         address = bindAddress.getHostAddress();
      return address;
   }

   public void setBindAddress(String host) throws UnknownHostException
   {
      bindAddress = InetAddress.getByName(host);
   }
   public void setBindAddress(InetAddress bindAddress)
   {
      this.bindAddress = bindAddress;
   }

   /**
    * Create a server socket on the specified port (port 0 indicates
    * an anonymous port).
    *
    * @param port the port number
    * @return the server socket on the specified port
    * @throws java.io.IOException if an I/O error occurs during server socket
    *    creation
    * @since 1.2
    */
   public ServerSocket createServerSocket(int port) throws IOException
   {
      ServerSocket activeSocket = new TimeoutServerSocket(port, backlog, bindAddress);
      return activeSocket;
   }

   public boolean equals(Object obj)
   {
      return obj instanceof TimeoutServerSocketFactory;
   }

   public int hashCode()
   {
      return getClass().getName().hashCode();
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.loading;

import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * A helper for context classloading.

 *
 * When a security manager is installed, the
 * constructor checks for the runtime permissions
 * "getClassLoader"
 *
 * @version <tt>$Revision$</tt>
 * @author  Adrian Brock
 */
@SuppressWarnings("unchecked")
public class ContextClassLoader
{
   /**
    * Retrieve a classloader permission
    */
   public static final RuntimePermission GETCLASSLOADER = new RuntimePermission("getClassLoader");

   /**
    * Instantiate a new context class loader
    */
   public static final NewInstance INSTANTIATOR = new NewInstance();

   /**
    * Constructor.
    *
    * @throws SecurityException when not authroized to get the context classloader
    */
   /*package*/ ContextClassLoader()
   {
      SecurityManager manager = System.getSecurityManager();
      if (manager != null)
      {
         manager.checkPermission(GETCLASSLOADER);
      }
   }

   /**
    * Retrieve the context classloader
    *
    * @return the context classloader
    */
   public ClassLoader getContextClassLoader()
   {
      return getContextClassLoader(Thread.currentThread());
   }

   /**
    * Retrieve the context classloader for the given thread
    *
    * @param thread the thread
    * @return the context classloader
    */
   public ClassLoader getContextClassLoader(final Thread thread)
   {
      return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction()
      {
         public Object run()
         {
            return thread.getContextClassLoader();
         }
      });
   }

   private static class NewInstance
      implements PrivilegedAction
   {
      public Object run()
      {
         return new ContextClassLoader();
      }
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.deadlock;

/**
 * This exception class is thrown when application deadlock is detected when trying to lock an entity bean
 * This is probably NOT a result of a jboss bug, but rather that the application is access the same entity
 * beans within 2 different transaction in a different order.  Remember, with a PessimisticEJBLock,
 * Entity beans are locked until the transaction commits or is rolled back.
 *
 * @author Bill Burke
 *
 * @version $Revision$
 *
 *
Revisions:

 *
2002/02/13: billb
 *

 *
Initial revision
 *

 */
public class ApplicationDeadlockException extends RuntimeException
{
   /** The serialVersionUID */
   private static final long serialVersionUID = -908428091244600395L;
   protected boolean retry = false;

   public ApplicationDeadlockException()
   {
      super();
   }

   public ApplicationDeadlockException(String msg, boolean retry)
   {
      super(msg);
      this.retry = retry;
   }

   public boolean retryable()
   {
      return retry;
   }

   /**
    * Detects exception contains is or a ApplicationDeadlockException.
    * @param t
    * @return  true when it is a deadlock
    */
   public static ApplicationDeadlockException isADE(Throwable t)
   {
      while (t!=null)
      {
         if (t instanceof ApplicationDeadlockException)
         {
            return (ApplicationDeadlockException)t;
         }
         else
         {
            t = t.getCause();
         }
      }
      return null;
   }

}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.timeout;

import java.util.concurrent.atomic.AtomicBoolean;

import org.jboss.util.NestedRuntimeException;
import org.jboss.util.ThrowableHandler;
import org.jboss.util.threadpool.BasicThreadPool;
import org.jboss.util.threadpool.BlockingMode;
import org.jboss.util.threadpool.ThreadPool;

/**
 * The timeout factory.
 *
 * @author Ole Husgaard
 * @author Dimitris Andreadis
 * @author Elias Ross
 * @author Adrian Brock
 * @version $Revision$
 */
@SuppressWarnings("unchecked")
public class TimeoutFactory
{
   /** The priority queue property */
   private static final String priorityQueueProperty = TimeoutPriorityQueue.class.getName();

   /** The priority queue default */
   private static final String priorityQueueName = TimeoutPriorityQueueImpl.class.getName();

   /** Our singleton instance */
   private static TimeoutFactory singleton;

   /** Number of TimeoutFactories created */
   private static int timeoutFactoriesCount = 0;

   /** The priority queue class */
   private static Class<?> priorityQueueClass;

   /** The default threadpool used to execute timeouts */
   private static BasicThreadPool DEFAULT_TP = new BasicThreadPool("Timeouts");
   static
   {
      DEFAULT_TP.setBlockingMode(BlockingMode.RUN);

      String priorityQueueClassName = priorityQueueName;
      ClassLoader cl = TimeoutFactory.class.getClassLoader();
      try
      {
         priorityQueueClassName = System.getProperty(priorityQueueProperty, priorityQueueName);
         cl = Thread.currentThread().getContextClassLoader();
      }
      catch (Exception ignored)
      {
      }

      try
      {
         priorityQueueClass = cl.loadClass(priorityQueueClassName);
      }
      catch (Exception e)
      {
         throw new NestedRuntimeException(e.toString(), e);
      }
   }

   /** Used for graceful exiting */
   private AtomicBoolean cancelled = new AtomicBoolean(false);

   /** The daemon thread that dequeues timeouts tasks and issues
       them for execution to the thread pool */
   private Thread workerThread;

   /** Per TimeoutFactory thread pool used to execute timeouts */
   private ThreadPool threadPool;

   /** The priority queue */
   private TimeoutPriorityQueue queue;

   public synchronized static TimeoutFactory getSingleton()
   {
      if (singleton == null)
      {
         singleton = new TimeoutFactory(DEFAULT_TP);
      }
      return singleton;
   }

   /**
    *  Schedules a new timeout using the singleton TimeoutFactory
    * @param time
    * @param target
    * @return  the timeout
    */
   static public Timeout createTimeout(long time, TimeoutTarget target)
   {
      return getSingleton().schedule(time, target);
   }

   /**
    * Constructs a new TimeoutFactory that uses the provided ThreadPool
    * @param threadPool
    */
   public TimeoutFactory(ThreadPool threadPool)
   {
      this.threadPool = threadPool;
      try
      {
         queue = (TimeoutPriorityQueue) priorityQueueClass.newInstance();
      }
      catch (Exception e)
      {
         throw new RuntimeException("Cannot instantiate " + priorityQueueClass,e);
      }

      // setup the workerThread
      workerThread = new Thread("TimeoutFactory-" + timeoutFactoriesCount++)
      {
         public void run()
         {
            doWork();
         }
      };
      workerThread.setDaemon(true);
      workerThread.start();
   }

   /**
    * Constructs a new TimeoutFactory that uses the default thread pool
    */
   public TimeoutFactory()
   {
      this(DEFAULT_TP);
   }

   /**
    * Schedules a new timeout.
    *
    * @param time absolute time
    * @param target target to fire
    * @return the timeout
    */
   public Timeout schedule(long time, TimeoutTarget target)
   {
      if (cancelled.get())
         throw new IllegalStateException("TimeoutFactory has been cancelled");
      if (time < 0)
         throw new IllegalArgumentException("Negative time");
      if (target == null)
         throw new IllegalArgumentException("Null timeout target");

      return queue.offer(time, target);
   }

   /**
    * Schedules a new timeout.
    *
    * @param time absolute time
    * @param run runnable to run
    * @return the timeout
    */
   public Timeout schedule(long time, Runnable run)
   {
      return schedule(time, new TimeoutTargetImpl(run));
   }

   /**
    * Cancels all submitted tasks, stops the worker
    * thread and clean-ups everything except for the
    * thread pool. Scheduling new timeouts after cancel
    * is called results in a IllegalStateException.
    */
   public void cancel()
   {
      // obviously the singleton TimeoutFactory cannot
      // be cancelled since its reference is not accessible

      // let the worker thread cleanup
      if (cancelled.getAndSet(true) == false)
      {
         // Cancel the priority queue
         queue.cancel();
      }
   }

   /**
    * @return true if the TimeoutFactory has been cancelled,
    * false if it is operational (i.e. accepts timeout schedules).
    */
   public boolean isCancelled()
   {
      return cancelled.get();
   }

   /**
    *  Timeout worker method.
    */
   private void doWork()
   {
      while (cancelled.get() == false)
      {
         TimeoutExt work = queue.take();
         // Do work, if any
         if (work != null)
         {
            // Wrap the TimeoutExt with a runnable that invokes the target callback
            TimeoutWorker worker = new TimeoutWorker(work);
            try
            {
               threadPool.run(worker);
            }
            catch (Throwable t)
            {
               // protect the worker thread from pool enqueue errors
               ThrowableHandler.add(ThrowableHandler.Type.ERROR, t);
            }
            synchronized (work)
            {
               work.done();
            }
         }
      }

      // TimeoutFactory was cancelled
      queue.cancel();
   }

   /**
    *  A runnable that fires the timeout callback
    */
   private static class TimeoutWorker implements Runnable
   {
      private TimeoutExt work;

      /**
       *  Create a new instance.
       *
       *  @param work The timeout that should be fired.
       */
      TimeoutWorker(TimeoutExt work)
      {
         this.work = work;
      }

      /**
       *  Override to fire the timeout.
       */
      public void run()
      {
         try
         {
            work.getTimeoutTarget().timedOut(work);
         }
         catch (Throwable t)
         {
            // protect the thread pool thread from receiving this error
            ThrowableHandler.add(ThrowableHandler.Type.ERROR, t);
         }
         synchronized (work)
         {
            work.done();
         }
      }
   }

   /**
    * Simple TimeoutTarget implementation that wraps a Runnable
    */
   private static class TimeoutTargetImpl implements TimeoutTarget
   {
      Runnable runnable;

      TimeoutTargetImpl(Runnable runnable)
      {
         this.runnable = runnable;
      }

      public void timedOut(Timeout ignored)
      {
         runnable.run();
      }
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.naming;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.LinkRef;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;

import org.jboss.logging.Logger;

/** A static utility class for common JNDI operations.
 *
 * @author Scott.Stark@jboss.org
 * @author adrian@jboss.com
 * @version $Revision$
 */
@SuppressWarnings("unchecked")
public class Util
{
   private static final Logger log = Logger.getLogger(Util.class);

   /** Create a subcontext including any intermediate contexts.
    @param ctx the parent JNDI Context under which value will be bound
    @param name the name relative to ctx of the subcontext.
    @return The new or existing JNDI subcontext
    @throws javax.naming.NamingException on any JNDI failure
    */
   public static Context createSubcontext(Context ctx, String name) throws NamingException
   {
      Name n = ctx.getNameParser("").parse(name);
      return createSubcontext(ctx, n);
   }

   /** Create a subcontext including any intermediate contexts.
    @param ctx the parent JNDI Context under which value will be bound
    @param name the name relative to ctx of the subcontext.
    @return The new or existing JNDI subcontext
    @throws NamingException on any JNDI failure
    */
   public static Context createSubcontext(Context ctx, Name name) throws NamingException
   {
      Context subctx = ctx;
      for (int pos = 0; pos < name.size(); pos++)
      {
         String ctxName = name.get(pos);
         try
         {
            subctx = (Context) ctx.lookup(ctxName);
         }
         catch (NameNotFoundException e)
         {
            subctx = ctx.createSubcontext(ctxName);
         }
         // The current subctx will be the ctx for the next name component
         ctx = subctx;
      }
      return subctx;
   }

   /** Bind val to name in ctx, and make sure that all intermediate contexts exist
    @param ctx the parent JNDI Context under which value will be bound
    @param name the name relative to ctx where value will be bound
    @param value the value to bind.
    @throws NamingException for any error
    */
   public static void bind(Context ctx, String name, Object value) throws NamingException
   {
      Name n = ctx.getNameParser("").parse(name);
      bind(ctx, n, value);
   }

   /** Bind val to name in ctx, and make sure that all intermediate contexts exist
    @param ctx the parent JNDI Context under which value will be bound
    @param name the name relative to ctx where value will be bound
    @param value the value to bind.
    @throws NamingException for any error
    */
   public static void bind(Context ctx, Name name, Object value) throws NamingException
   {
      int size = name.size();
      String atom = name.get(size - 1);
      Context parentCtx = createSubcontext(ctx, name.getPrefix(size - 1));
      parentCtx.bind(atom, value);
   }

   /** Rebind val to name in ctx, and make sure that all intermediate contexts exist
    @param ctx the parent JNDI Context under which value will be bound
    @param name the name relative to ctx where value will be bound
    @param value the value to bind.
    @throws NamingException for any error
    */
   public static void rebind(Context ctx, String name, Object value) throws NamingException
   {
      Name n = ctx.getNameParser("").parse(name);
      rebind(ctx, n, value);
   }

   /** Rebind val to name in ctx, and make sure that all intermediate contexts exist
    @param ctx the parent JNDI Context under which value will be bound
    @param name the name relative to ctx where value will be bound
    @param value the value to bind.
    @throws NamingException for any error
    */
   public static void rebind(Context ctx, Name name, Object value) throws NamingException
   {
      int size = name.size();
      String atom = name.get(size - 1);
      Context parentCtx = createSubcontext(ctx, name.getPrefix(size - 1));
      parentCtx.rebind(atom, value);
   }

   /** Unbinds a name from ctx, and removes parents if they are empty
    @param ctx the parent JNDI Context under which the name will be unbound
    @param name The name to unbind
    @throws NamingException for any error
    */
   public static void unbind(Context ctx, String name) throws NamingException
   {
      unbind(ctx, ctx.getNameParser("").parse(name));
   }

   /** Unbinds a name from ctx, and removes parents if they are empty
    @param ctx the parent JNDI Context under which the name will be unbound
    @param name The name to unbind
    @throws NamingException for any error
    */
   public static void unbind(Context ctx, Name name) throws NamingException
   {
      ctx.unbind(name); //unbind the end node in the name
      int sz = name.size();
      // walk the tree backwards, stopping at the domain
      while (--sz > 0)
      {
         Name pname = name.getPrefix(sz);
         try
         {
            ctx.destroySubcontext(pname);
         }
         catch (NamingException e)
         {
            log.trace("Unable to remove context " + pname, e);
            break;
         }
      }
   }

   /**
    * Lookup an object in the default initial context
    *
    * @param name the name to lookup
    * @param clazz the expected type
    * @return the object
    * @throws Exception for any error
    */
   public static Object lookup(String name, Class<?> clazz) throws Exception
   {
      InitialContext ctx = new InitialContext();
      try
      {
         return lookup(ctx, name, clazz);
      }
      finally
      {
         ctx.close();
      }
   }

   /**
    * Lookup an object in the default initial context
    *
    * @param name the name to lookup
    * @param clazz the expected type
    * @return the object
    * @throws Exception for any error
    */
   public static Object lookup(Name name, Class<?> clazz) throws Exception
   {
      InitialContext ctx = new InitialContext();
      try
      {
         return lookup(ctx, name, clazz);
      }
      finally
      {
         ctx.close();
      }
   }

   /**
    * Lookup an object in the given context
    *
    * @param context the context
    * @param name the name to lookup
    * @param clazz the expected type
    * @return the object
    * @throws Exception for any error
    */
   public static Object lookup(Context context, String name, Class clazz) throws Exception
   {
      Object result = context.lookup(name);
      checkObject(context, name, result, clazz);
      return result;
   }

   /**
    * Lookup an object in the given context
    *
    * @param context the context
    * @param name the name to lookup
    * @param clazz the expected type
    * @return the object
    * @throws Exception for any error
    */
   public static Object lookup(Context context, Name name, Class clazz) throws Exception
   {
      Object result = context.lookup(name);
      checkObject(context, name.toString(), result, clazz);
      return result;
   }

   /**
    * Create a link
    *
    * @param fromName the from name
    * @param toName the to name
    * @throws NamingException for any error
    */
   public static void createLinkRef(String fromName, String toName) throws NamingException
   {
      InitialContext ctx = new InitialContext();
      createLinkRef(ctx, fromName, toName);
   }

   /**
    * Create a link
    *
    * @param ctx the context
    * @param fromName the from name
    * @param toName the to name
    * @throws NamingException for any error
    */
   public static void createLinkRef(Context ctx, String fromName, String toName) throws NamingException
   {
      LinkRef link = new LinkRef(toName);
      Context fromCtx = ctx;
      Name name = ctx.getNameParser("").parse(fromName);
      String atom = name.get(name.size()-1);
      for(int n = 0; n < name.size()-1; n ++)
      {
         String comp = name.get(n);
         try
         {
            fromCtx = (Context) fromCtx.lookup(comp);
         }
         catch(NameNotFoundException e)
         {
            fromCtx = fromCtx.createSubcontext(comp);
         }
      }

      log.debug("atom: " + atom);
      log.debug("link: " + link);

      fromCtx.rebind(atom, link);

      log.debug("Bound link " + fromName + " to " + toName);
   }

   /**
    * Remove the link ref
    *
    * @param name the name of the link binding
    * @throws NamingException for any error
    */
   public static void removeLinkRef(String name) throws NamingException
   {
      InitialContext ctx = new InitialContext();
      removeLinkRef(ctx, name);
   }

   /**
    * Remove the link ref
    *
    * @param ctx the context
    * @param name the name of the link binding
    * @throws NamingException for any error
    */
   public static void removeLinkRef(Context ctx, String name) throws NamingException
   {
      log.debug("Unbinding link " + name);
      ctx.unbind(name);
   }

   /**
    * Checks an object implements the given class
    *
    * @param context the context
    * @param name the name to lookup
    * @param object the object
    * @param clazz the expected type
    * @throws Exception for any error
    */
   protected static void checkObject(Context context, String name, Object object, Class clazz) throws Exception
   {
      Class objectClass = object.getClass();
      if (clazz.isAssignableFrom(objectClass) == false)
      {
         StringBuffer buffer = new StringBuffer(100);
         buffer.append("Object at '").append(name);
         buffer.append("' in context ").append(context.getEnvironment());
         buffer.append(" is not an instance of ");
         appendClassInfo(buffer, clazz);
         buffer.append(" object class is ");
         appendClassInfo(buffer, object.getClass());
         throw new ClassCastException(buffer.toString());
      }
   }

   /**
    * Append Class Info
    *
    * @param buffer the buffer to append to
    * @param clazz the class to describe
    */
   protected static void appendClassInfo(StringBuffer buffer, Class clazz)
   {
      buffer.append("[class=").append(clazz.getName());
      buffer.append(" classloader=").append(clazz.getClassLoader());
      buffer.append(" interfaces={");
      Class[] interfaces = clazz.getInterfaces();
      for (int i=0; i<interfaces.length; ++i)
      {
         if (i > 0)
            buffer.append(", ");
         buffer.append("interface=").append(interfaces[i].getName());
         buffer.append(" classloader=").append(interfaces[i].getClassLoader());
      }
      buffer.append("}]");
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.state;

import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;

/** The respresentation of a state in a state machine.
 *
 * @author Scott.Stark@jboss.org
 * @version $Revision$
 */
@SuppressWarnings("unchecked")
public class State
{
   /** The name of the state */
   private String name;
   /** HashMap<String, Transition> */
   private HashMap allowedTransitions = new HashMap();
   /** Arbitrary state data */
   private Object data;

   public State(String name)
   {
      this(name, null);
   }
   public State(String name, Map transitions)
   {
      this.name = name;
      if( transitions != null )
      {
         allowedTransitions.putAll(transitions);
      }
   }

   /** Get the state name.
    * @return the name of the state.
    */
   public String getName()
   {
      return name;
   }

   public Object getData()
   {
      return data;
   }
   public void setData(Object data)
   {
      this.data = data;
   }

   /** An accept state is indicated by no transitions
    * @return true if this is an accept state, false otherwise.
    */
   public boolean isAcceptState()
   {
      return allowedTransitions.size() == 0;
   }

   /** Add a transition to the allowed transition map.
    *
    * @param transition
    * @return this to allow chained addTransition calls
    */
   public State addTransition(Transition transition)
   {
      allowedTransitions.put(transition.getName(), transition);
      return this;
   }

   /** Lookup an allowed transition given its name.
    *
    * @param name - the name of a valid transition from this state.
    * @return the valid transition if it exists, null otherwise.
    */
   public Transition getTransition(String name)
   {
      Transition t = (Transition) allowedTransitions.get(name);
      return t;
   }

   /** Get the Map<String, Transition> of allowed transitions for this state.
    * @return the allowed transitions map.
    */
   public Map getTransitions()
   {
      return allowedTransitions;
   }

   public String toString()
   {
      StringBuffer tmp = new StringBuffer("State(name=");
      tmp.append(name);
      Iterator i = allowedTransitions.entrySet().iterator();
      while( i.hasNext() )
      {
         Map.Entry e = (Map.Entry) i.next();
         tmp.append("\n\t on: ");
         tmp.append(e.getKey());
         Transition t = (Transition) e.getValue();
         tmp.append(" go to: ");
         tmp.append(t.getTarget().getName());
      }
      tmp.append(')');
      return tmp.toString();
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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.
 */

// CatalogManager.java - Access CatalogManager.properties

package org.jboss.util.xml.catalog;

import java.io.InputStream;

import java.net.URL;
import java.net.MalformedURLException;

import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.Vector;

import org.jboss.util.xml.catalog.Catalog;
import org.jboss.util.xml.catalog.helpers.BootstrapResolver;
import org.jboss.util.xml.catalog.helpers.Debug;

/**
 * CatalogManager provides an interface to the catalog properties.
 *
 *
Properties can come from two places: from system properties or
 * from a CatalogManager.properties file. This class provides a transparent
 * interface to both, with system properties preferred over property file values.

 *
 *
The following table summarizes the properties:

 *
 *

 *

 *

 * System Property
 * CatalogManager.properties
Property
 * Description
 *

 *

 *

 *

 * xml.catalog.ignoreMissing
 *
 * If true, a missing CatalogManager.properties file or missing properties
 * within that file will not generate warning messages. See also the
 * ignoreMissingProperties method.
 *

 *
 *

 * xml.catalog.files
 * catalogs
 * The <emph>semicolon-delimited</emph> list of catalog files.
 *

 *
 *

 *
 * relative-catalogs
 * If false, relative catalog URIs are made absolute with respect to the base URI of
 * the CatalogManager.properties file. This setting only applies to catalog
 * URIs obtained from the catalogs property <emph>in the</emph>
 * CatalogManager.properties file
 *

 *
 *

 * xml.catalog.verbosity
 * verbosity
 * If non-zero, the Catalog classes will print informative and debugging messages.
 * The higher the number, the more messages.
 *

 *
 *

 * xml.catalog.prefer
 * prefer
 * Which identifier is preferred, "public" or "system"?
 *

 *
 *

 * xml.catalog.staticCatalog
 * static-catalog
 * Should a single catalog be constructed for all parsing, or should a different
 * catalog be created for each parser?
 *

 *
 *

 * xml.catalog.allowPI
 * allow-oasis-xml-catalog-pi
 * If the source document contains "oasis-xml-catalog" processing instructions,
 * should they be used?
 *

 *
 *

 * xml.catalog.className
 * catalog-class-name
 * If you're using the convenience classes
 * <tt>org.apache.xml.resolver.tools.*</tt>), this setting
 * allows you to specify an alternate class name to use for the underlying
 * catalog.
 *

 *

 *

 *
 * @see Catalog
 *
 * @author Norman Walsh
 * Norman.Walsh@Sun.COM
 *
 * @version 1.0
 */

@SuppressWarnings("unchecked")
public class CatalogManager {
  private static String pFiles         = "xml.catalog.files";
  private static String pVerbosity     = "xml.catalog.verbosity";
  private static String pPrefer        = "xml.catalog.prefer";
  private static String pStatic        = "xml.catalog.staticCatalog";
  private static String pAllowPI       = "xml.catalog.allowPI";
  private static String pClassname     = "xml.catalog.className";
  private static String pIgnoreMissing = "xml.catalog.ignoreMissing";

  /** A static CatalogManager instance for sharing */
  private static CatalogManager staticManager = new CatalogManager();

  /** The bootstrap resolver to use when loading XML Catalogs. */
  private BootstrapResolver bResolver = new BootstrapResolver();

  /** Flag to ignore missing property files and/or properties */
  private boolean ignoreMissingProperties
    = (System.getProperty(pIgnoreMissing) != null
       || System.getProperty(pFiles) != null);

  /** Holds the resources after they are loaded from the file. */
  private ResourceBundle resources;

  /** The name of the CatalogManager properties file. */
  private String propertyFile = "CatalogManager.properties";

  /** The location of the propertyFile */
  private URL propertyFileURI = null;

  /** Default catalog files list. */
  private String defaultCatalogFiles = "./xcatalog";

  /** Current catalog files list. */
  private String catalogFiles = null;

  /** Did the catalgoFiles come from the properties file? */
  private boolean fromPropertiesFile = false;

  /** Default verbosity level if there is no property setting for it. */
  private int defaultVerbosity = 1;

  /** Current verbosity level. */
  private Integer verbosity = null;

  /** Default preference setting. */
  private boolean defaultPreferPublic = true;

  /** Current preference setting. */
  private Boolean preferPublic = null;

  /** Default setting of the static catalog flag. */
  private boolean defaultUseStaticCatalog = true;

  /** Current setting of the static catalog flag. */
  private Boolean useStaticCatalog = null;

  /** The static catalog used by this manager. */
  private static Catalog staticCatalog = null;

  /** Default setting of the oasisXMLCatalogPI flag. */
  private boolean defaultOasisXMLCatalogPI = true;

  /** Current setting of the oasisXMLCatalogPI flag. */
  private Boolean oasisXMLCatalogPI = null;

  /** Default setting of the relativeCatalogs flag. */
  private boolean defaultRelativeCatalogs = true;

  /** Current setting of the relativeCatalogs flag. */
  private Boolean relativeCatalogs = null;

  /** Current catalog class name. */
  private String catalogClassName = null;

  /** The manager's debug object. Used for printing debugging messages.
   *
   *
This field is public so that objects that have access to this
   * CatalogManager can use this debug object.

   */
  public Debug debug = null;

  /** Constructor. */
  public CatalogManager() {
    debug = new Debug();
    // Note that we don't setDebug() here; we do that lazily. Either the
    // user will set it explicitly, or we'll do it automagically if they
    // read from the propertyFile for some other reason. That way, there's
    // no attempt to read from the file before the caller has had a chance
    // to avoid it.
  }

  /** Constructor that specifies an explicit property file.
 * @param propertyFile */
  public CatalogManager(String propertyFile) {
    this.propertyFile = propertyFile;

    debug = new Debug();
    // Note that we don't setDebug() here; we do that lazily. Either the
    // user will set it explicitly, or we'll do it automagically if they
    // read from the propertyFile for some other reason. That way, there's
    // no attempt to read from the file before the caller has had a chance
    // to avoid it.
  }

  /** Set the bootstrap resolver.
 * @param resolver */
  public void setBootstrapResolver(BootstrapResolver resolver) {
    bResolver = resolver;
  }

  /** @return the bootstrap resolver.*/
  public BootstrapResolver getBootstrapResolver() {
    return bResolver;
  }

  /**
   * Load the properties from the propertyFile and build the
   * resources from it.
   */
  private synchronized void readProperties() {
    try {
      propertyFileURI = CatalogManager.class.getResource("/"+propertyFile);
      InputStream in =
	CatalogManager.class.getResourceAsStream("/"+propertyFile);
      if (in==null) {
	if (!ignoreMissingProperties) {
	  System.err.println("Cannot find "+propertyFile);
	  // there's no reason to give this warning more than once
	  ignoreMissingProperties = true;
	}
	return;
      }
      resources = new PropertyResourceBundle(in);
    } catch (MissingResourceException mre) {
      if (!ignoreMissingProperties) {
	System.err.println("Cannot read "+propertyFile);
      }
    } catch (java.io.IOException e) {
      if (!ignoreMissingProperties) {
	System.err.println("Failure trying to read "+propertyFile);
      }
    }

    // This is a bit of a hack. After we've successfully read the properties,
    // use them to set the default debug level, if the user hasn't already set
    // the default debug level.
    if (verbosity == null) {
      try {
	String verbStr = resources.getString("verbosity");
	int verb = Integer.parseInt(verbStr.trim());
	debug.setDebug(verb);
	verbosity = new Integer(verb);
      } catch (Exception e) {
	// nop
      }
    }
  }

  /**
   * Allow access to the static CatalogManager
   * @return the catalog manager
   */
  public static CatalogManager getStaticManager() {
    return staticManager;
  }

  /**
   * How are missing properties handled?
   *
   *
If true, missing or unreadable property files will
   * not be reported. Otherwise, a message will be sent to System.err.
   *

   * @return the value
   */
  public boolean getIgnoreMissingProperties() {
    return ignoreMissingProperties;
  }

  /**
   * How should missing properties be handled?
   *
   *
If ignore is true, missing or unreadable property files will
   * not be reported. Otherwise, a message will be sent to System.err.
   *

 * @param ignore
   */
  public void setIgnoreMissingProperties(boolean ignore) {
    ignoreMissingProperties = ignore;
  }

  /**
   * How are missing properties handled?
   *
   *
If ignore is true, missing or unreadable property files will
   * not be reported. Otherwise, a message will be sent to System.err.
   *

 * @param ignore
   *
   * @deprecated No longer static; use get/set methods.
   */
  public void ignoreMissingProperties(boolean ignore) {
    setIgnoreMissingProperties(ignore);
  }

  /**
   * Obtain the verbosity setting from the properties.
   *
   * @return The verbosity level from the propertyFile or the
   * defaultVerbosity.
   */
  private int queryVerbosity () {
    String verbStr = System.getProperty(pVerbosity);

    if (verbStr == null) {
      if (resources==null) readProperties();
      if (resources==null) return defaultVerbosity;
      try {
	verbStr = resources.getString("verbosity");
      } catch (MissingResourceException e) {
	return defaultVerbosity;
      }
    }

    try {
      int verb = Integer.parseInt(verbStr.trim());
      return verb;
    } catch (Exception e) {
      System.err.println("Cannot parse verbosity: \"" + verbStr + "\"");
      return defaultVerbosity;
    }
  }

  /**
   * @return the current verbosity?
   */
  public int getVerbosity() {
    if (verbosity == null) {
      verbosity = new Integer(queryVerbosity());
    }

    return verbosity.intValue();
  }

  /**
   * Set the current verbosity.
 * @param verbosity
   */
  public void setVerbosity (int verbosity) {
    this.verbosity = new Integer(verbosity);
    debug.setDebug(verbosity);
  }

  /**
   * @return the current verbosity?
   *
   * @deprecated No longer static; use get/set methods.
   */
  public int verbosity () {
    return getVerbosity();
  }

  /**
   * Obtain the relativeCatalogs setting from the properties.
   *
   * @return The relativeCatalogs setting from the propertyFile or the
   * defaultRelativeCatalogs.
   */
  private boolean queryRelativeCatalogs () {
    if (resources==null) readProperties();

    if (resources==null) return defaultRelativeCatalogs;

    try {
      String allow = resources.getString("relative-catalogs");
      return (allow.equalsIgnoreCase("true")
	      || allow.equalsIgnoreCase("yes")
	      || allow.equalsIgnoreCase("1"));
    } catch (MissingResourceException e) {
      return defaultRelativeCatalogs;
    }
  }

  /**
   * Get the relativeCatalogs setting.
   *
   *
This property is used when the catalogFiles property is
   * interrogated. If true, then relative catalog entry file names
   * are returned. If false, relative catalog entry file names are
   * made absolute with respect to the properties file before returning
   * them.

   *
   *
This property <emph>only applies</emph> when the catalog files
   * come from a properties file. If they come from a system property or
   * the default list, they are never considered relative. (What would
   * they be relative to?)

   *
   *
In the properties, a value of 'yes', 'true', or '1' is considered
   * true, anything else is false.

   *
   * @return The relativeCatalogs setting from the propertyFile or the
   * defaultRelativeCatalogs.
   */
  public boolean getRelativeCatalogs () {
    if (relativeCatalogs == null) {
      relativeCatalogs = new Boolean(queryRelativeCatalogs());
    }

    return relativeCatalogs.booleanValue();
  }

  /**
   * Set the relativeCatalogs setting.
   * @param relative
   *
   * @see #getRelativeCatalogs()
   */
  public void setRelativeCatalogs (boolean relative) {
    relativeCatalogs = new Boolean(relative);
  }

  /**
   * @return the relativeCatalogs setting.
   *
   * @deprecated No longer static; use get/set methods.
   */
  public boolean relativeCatalogs () {
    return getRelativeCatalogs();
  }

  /**
   * Obtain the list of catalog files from the properties.
   *
   * @return A semicolon delimited list of catlog file URIs
   */
  private String queryCatalogFiles () {
    String catalogList = System.getProperty(pFiles);
    fromPropertiesFile = false;

    if (catalogList == null) {
      if (resources == null) readProperties();
      if (resources != null) {
	try {
	  catalogList = resources.getString("catalogs");
	  fromPropertiesFile = true;
	} catch (MissingResourceException e) {
	  System.err.println(propertyFile + ": catalogs not found.");
	  catalogList = null;
	}
      }
    }

    if (catalogList == null) {
      catalogList = defaultCatalogFiles;
    }

    return catalogList;
  }

  /**
   * Return the current list of catalog files.
   *
   * @return A vector of the catalog file names or null if no catalogs
   * are available in the properties.
   */
  public Vector getCatalogFiles() {
    if (catalogFiles == null) {
      catalogFiles = queryCatalogFiles();
    }

    StringTokenizer files = new StringTokenizer(catalogFiles, ";");
    Vector catalogs = new Vector();
    while (files.hasMoreTokens()) {
      String catalogFile = files.nextToken();
      URL absURI = null;

      if (fromPropertiesFile && !relativeCatalogs()) {
	try {
	  absURI = new URL(propertyFileURI, catalogFile);
	  catalogFile = absURI.toString();
	} catch (MalformedURLException mue) {
	  absURI = null;
	}
      }

      catalogs.add(catalogFile);
    }

    return catalogs;
  }

  /**
   * Set the list of catalog files.
 * @param fileList
   */
  public void setCatalogFiles(String fileList) {
    catalogFiles = fileList;
    fromPropertiesFile = false;
  }

  /**
   * Return the current list of catalog files.
   *
   * @return A vector of the catalog file names or null if no catalogs
   * are available in the properties.
   *
   * @deprecated No longer static; use get/set methods.
   */
  public Vector catalogFiles() {
    return getCatalogFiles();
  }

  /**
   * Obtain the preferPublic setting from the properties.
   *
   *
In the properties, a value of 'public' is true,
   * anything else is false.

   *
   * @return True if prefer is public or the
   * defaultPreferSetting.
   */
  private boolean queryPreferPublic () {
    String prefer = System.getProperty(pPrefer);

    if (prefer == null) {
      if (resources==null) readProperties();
      if (resources==null) return defaultPreferPublic;
      try {
	prefer = resources.getString("prefer");
      } catch (MissingResourceException e) {
	return defaultPreferPublic;
      }
    }

    if (prefer == null) {
      return defaultPreferPublic;
    }

    return (prefer.equalsIgnoreCase("public"));
  }

  /**
   * Return the current prefer public setting.
   *
   * @return True if public identifiers are preferred.
   */
  public boolean getPreferPublic () {
    if (preferPublic == null) {
      preferPublic = new Boolean(queryPreferPublic());
    }
    return preferPublic.booleanValue();
  }

  /**
   * Set the prefer public setting.
   * @param preferPublic
   */
  public void setPreferPublic (boolean preferPublic) {
    this.preferPublic = new Boolean(preferPublic);
  }

  /**
   * Return the current prefer public setting.
   *
   * @return True if public identifiers are preferred.
   *
   * @deprecated No longer static; use get/set methods.
   */
  public boolean preferPublic () {
    return getPreferPublic();
  }

  /**
   * Obtain the static-catalog setting from the properties.
   *
   *
In the properties, a value of 'yes', 'true', or '1' is considered
   * true, anything else is false.

   *
   * @return The static-catalog setting from the propertyFile or the
   * defaultUseStaticCatalog.
   */
  private boolean queryUseStaticCatalog () {
    String staticCatalog = System.getProperty(pStatic);

    if (useStaticCatalog == null) {
      if (resources==null) readProperties();
      if (resources==null) return defaultUseStaticCatalog;
      try {
	staticCatalog = resources.getString("static-catalog");
      } catch (MissingResourceException e) {
	return defaultUseStaticCatalog;
      }
    }

    if (staticCatalog == null) {
      return defaultUseStaticCatalog;
    }

    return (staticCatalog.equalsIgnoreCase("true")
	    || staticCatalog.equalsIgnoreCase("yes")
	    || staticCatalog.equalsIgnoreCase("1"));
  }

  /**
   * @return the current use static catalog setting.
   */
  public boolean getUseStaticCatalog() {
    if (useStaticCatalog == null) {
      useStaticCatalog = new Boolean(queryUseStaticCatalog());
    }

    return useStaticCatalog.booleanValue();
  }

  /**
   * Set the use static catalog setting.
 * @param useStatic
   */
  public void setUseStaticCatalog(boolean useStatic) {
    useStaticCatalog = new Boolean(useStatic);
  }

  /**
   * @return the current use static catalog setting.
   *
   * @deprecated No longer static; use get/set methods.
   */
  public boolean staticCatalog() {
    return getUseStaticCatalog();
  }

  /**
   * @return a new catalog instance.
   *
   * This method always returns a new instance of the underlying catalog class.
   */
  public Catalog getPrivateCatalog() {
    Catalog catalog = staticCatalog;

    if (useStaticCatalog == null) {
      useStaticCatalog = new Boolean(getUseStaticCatalog());
    }

    if (catalog == null || !useStaticCatalog.booleanValue()) {

      try {
	String catalogClassName = getCatalogClassName();

	if (catalogClassName == null) {
	  catalog = new Catalog();
	} else {
	  try {
	    catalog = (Catalog) Class.forName(catalogClassName).newInstance();
	  } catch (ClassNotFoundException cnfe) {
	    debug.message(1,"Catalog class named '"
			  + catalogClassName
			  + "' could not be found. Using default.");
	    catalog = new Catalog();
	  } catch (ClassCastException cnfe) {
	    debug.message(1,"Class named '"
			  + catalogClassName
		  + "' is not a Catalog. Using default.");
	    catalog = new Catalog();
	  }
	}

	catalog.setCatalogManager(this);
	catalog.setupReaders();
	catalog.loadSystemCatalogs();
      } catch (Exception ex) {
	ex.printStackTrace();
      }

      if (useStaticCatalog.booleanValue()) {
	staticCatalog = catalog;
      }
    }

    return catalog;
  }

  /**
   * @return a catalog instance.
   *
   * If this manager uses static catalogs, the same static catalog will
   * always be returned. Otherwise a new catalog will be returned.
   */
  public Catalog getCatalog() {
    Catalog catalog = staticCatalog;

    if (useStaticCatalog == null) {
      useStaticCatalog = new Boolean(getUseStaticCatalog());
    }

    if (catalog == null || !useStaticCatalog.booleanValue()) {
      catalog = getPrivateCatalog();
      if (useStaticCatalog.booleanValue()) {
	staticCatalog = catalog;
      }
    }

    return catalog;
  }

  /**
   *
Obtain the oasisXMLCatalogPI setting from the properties.

   *
   *
In the properties, a value of 'yes', 'true', or '1' is considered
   * true, anything else is false.

   *
   * @return The oasisXMLCatalogPI setting from the propertyFile or the
   * defaultOasisXMLCatalogPI.
   */
  public boolean queryAllowOasisXMLCatalogPI () {
    String allow = System.getProperty(pAllowPI);

    if (allow == null) {
      if (resources==null) readProperties();
      if (resources==null) return defaultOasisXMLCatalogPI;
      try {
	allow = resources.getString("allow-oasis-xml-catalog-pi");
      } catch (MissingResourceException e) {
	return defaultOasisXMLCatalogPI;
      }
    }

    if (allow == null) {
      return defaultOasisXMLCatalogPI;
    }

    return (allow.equalsIgnoreCase("true")
	    || allow.equalsIgnoreCase("yes")
	    || allow.equalsIgnoreCase("1"));
  }

  /**
   * @return the current XML Catalog PI setting.
   */
  public boolean getAllowOasisXMLCatalogPI () {
    if (oasisXMLCatalogPI == null) {
      oasisXMLCatalogPI = new Boolean(queryAllowOasisXMLCatalogPI());
    }

    return oasisXMLCatalogPI.booleanValue();
  }

  /**
   * Set the XML Catalog PI setting
   * @param allowPI
   */
  public void setAllowOasisXMLCatalogPI(boolean allowPI) {
    oasisXMLCatalogPI = new Boolean(allowPI);
  }

  /**
   * @return the current XML Catalog PI setting.
   *
   * @deprecated No longer static; use get/set methods.
   */
  public boolean allowOasisXMLCatalogPI() {
    return getAllowOasisXMLCatalogPI();
  }

  /**
   * Obtain the Catalog class name setting from the properties.
   * @return the name
   *
   */
  public String queryCatalogClassName () {
    String className = System.getProperty(pClassname);

    if (className == null) {
      if (resources==null) readProperties();
      if (resources==null) return null;
      try {
	return resources.getString("catalog-class-name");
      } catch (MissingResourceException e) {
	return null;
      }
    }

    return className;
  }

  /**
   * @return the current Catalog class name.
   */
  public String getCatalogClassName() {
    if (catalogClassName == null) {
      catalogClassName = queryCatalogClassName();
    }

    return catalogClassName;
  }

  /**
   * Set the Catalog class name.
 * @param className
   */
  public void setCatalogClassName(String className) {
    catalogClassName = className;
  }

  /**
   * @return the current Catalog class name.
   *
   * @deprecated No longer static; use get/set methods.
   */
  public String catalogClassName() {
    return getCatalogClassName();
  }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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.
 */

// BootstrapResolver.java - Resolve entities and URIs internally

package org.jboss.util.xml.catalog.helpers;

import java.util.Hashtable;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.InputStream;

import javax.xml.transform.URIResolver;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.TransformerException;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;

/**
 * A simple bootstrapping resolver.
 *
 *
This class is used as the entity resolver when reading XML Catalogs.
 * It searches for the OASIS XML Catalog DTD, Relax NG Grammar and W3C XML Schema
 * as resources (e.g., in the resolver jar file).

 *
 *
If you have your own DTDs or schemas, you can extend this class and
 * set the BootstrapResolver in your CatalogManager.

 *
 * @see org.jboss.util.xml.catalog.CatalogManager
 *
 * @author Norman Walsh
 * Norman.Walsh@Sun.COM
 *
 * @version 1.0
 */
@SuppressWarnings("unchecked")
public class BootstrapResolver implements EntityResolver, URIResolver {
  /** URI of the W3C XML Schema for OASIS XML Catalog files. */
  public static final String xmlCatalogXSD = "http://www.oasis-open.org/committees/entity/release/1.0/catalog.xsd";

  /** URI of the RELAX NG Grammar for OASIS XML Catalog files. */
  public static final String xmlCatalogRNG = "http://www.oasis-open.org/committees/entity/release/1.0/catalog.rng";

  /** Public identifier for OASIS XML Catalog files. */
  public static final String xmlCatalogPubId = "-//OASIS//DTD XML Catalogs V1.0//EN";

  /** System identifier for OASIS XML Catalog files. */
  public static final String xmlCatalogSysId = "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd";

  /** Private hash used for public identifiers. */
  private Hashtable publicMap = new Hashtable();

  /** Private hash used for system identifiers. */
  private Hashtable systemMap = new Hashtable();

  /** Private hash used for URIs. */
  private Hashtable uriMap = new Hashtable();

  /** Constructor. */
  public BootstrapResolver() {
    URL url = this.getClass().getResource("/org/apache/xml/resolver/etc/catalog.dtd");
    if (url != null) {
      publicMap.put(xmlCatalogPubId, url.toString());
      systemMap.put(xmlCatalogSysId, url.toString());
    }

    url = this.getClass().getResource("/org/apache/xml/resolver/etc/catalog.rng");
    if (url != null) {
      uriMap.put(xmlCatalogRNG, url.toString());
    }

    url = this.getClass().getResource("/org/apache/xml/resolver/etc/catalog.xsd");
    if (url != null) {
      uriMap.put(xmlCatalogXSD, url.toString());
    }
  }

  /** SAX resolveEntity API. */
  public InputSource resolveEntity (String publicId, String systemId) {
    String resolved = null;

    if (systemId != null && systemMap.containsKey(systemId)) {
      resolved = (String) systemMap.get(systemId);
    } else if (publicId != null && publicMap.containsKey(publicId)) {
      resolved = (String) publicMap.get(publicId);
    }

    if (resolved != null) {
      try {
	InputSource iSource = new InputSource(resolved);
	iSource.setPublicId(publicId);

	// Ideally this method would not attempt to open the
	// InputStream, but there is a bug (in Xerces, at least)
	// that causes the parser to mistakenly open the wrong
	// system identifier if the returned InputSource does
	// not have a byteStream.
	//
	// It could be argued that we still shouldn't do this here,
	// but since the purpose of calling the entityResolver is
	// almost certainly to open the input stream, it seems to
	// do little harm.
	//
	URL url = new URL(resolved);
	InputStream iStream = url.openStream();
	iSource.setByteStream(iStream);

	return iSource;
      } catch (Exception e) {
	// FIXME: silently fail?
	return null;
      }
    }

    return null;
  }

  /** Transformer resolve API. */
  public Source resolve(String href, String base)
    throws TransformerException {

    String uri = href;
    int hashPos = href.indexOf("#");
    if (hashPos >= 0) {
      uri = href.substring(0, hashPos);
    }

    String result = null;
    if (href != null && uriMap.containsKey(href)) {
      result = (String) uriMap.get(href);
    }

    if (result == null) {
      try {
	URL url = null;

	if (base==null) {
	  url = new URL(uri);
	  result = url.toString();
	} else {
	  URL baseURL = new URL(base);
	  url = (href.length()==0 ? baseURL : new URL(baseURL, uri));
	  result = url.toString();
	}
      } catch (java.net.MalformedURLException mue) {
	// try to make an absolute URI from the current base
	String absBase = makeAbsolute(base);
	if (!absBase.equals(base)) {
	  // don't bother if the absBase isn't different!
	  return resolve(href, absBase);
	} else {
	  throw new TransformerException("Malformed URL "
					 + href + "(base " + base + ")",
					 mue);
	}
      }
    }

    SAXSource source = new SAXSource();
    source.setInputSource(new InputSource(result));
    return source;
  }

  /** Attempt to construct an absolute URI */
  private String makeAbsolute(String uri) {
    if (uri == null) {
      uri = "";
    }

    try {
      URL url = new URL(uri);
      return url.toString();
    } catch (MalformedURLException mue) {
      String dir = System.getProperty("user.dir");
      String file = "";

      if (dir.endsWith("/")) {
	file = "file://" + dir + uri;
      } else {
	file = "file://" + dir + "/" + uri;
      }

      try {
	URL fileURL = new URL(file);
	return fileURL.toString();
      } catch (MalformedURLException mue2) {
	// bail
	return uri;
      }
    }
  }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.stream;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.util.HashMap;
import java.util.Map;

/**
 * An ObjectInputStream subclass used by the MarshalledValue class to
 * ensure the classes and proxies are loaded using the thread context
 * class loader.
 *
 * @author Scott.Stark@jboss.org
 * @version $Revision: 37406 $
 */
public class MarshalledValueInputStream
      extends ObjectInputStream
{
   private static final Map<String, Class> primClasses = new HashMap<String, Class>(8, 1.0F);

   static
   {
      primClasses.put("boolean", boolean.class);
      primClasses.put("byte", byte.class);
      primClasses.put("char", char.class);
      primClasses.put("short", short.class);
      primClasses.put("int", int.class);
      primClasses.put("long", long.class);
      primClasses.put("float", float.class);
      primClasses.put("double", double.class);
      primClasses.put("void", void.class);
   }

   /**
    * Creates a new instance of MarshalledValueOutputStream
    *
    * @param is
    * @throws IOException
    */
   public MarshalledValueInputStream(InputStream is) throws IOException
   {
      super(is);
   }

   /**
    * Use the thread context class loader to resolve the class
    *
    * @throws java.io.IOException Any exception thrown by the underlying OutputStream.
    */
   protected Class<?> resolveClass(ObjectStreamClass v)
         throws IOException, ClassNotFoundException
   {
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      String className = v.getName();
      try
      {
         // JDK 6, by default, only supports array types (ex. [[B)  using Class.forName()
         return Class.forName(className, false, loader);
      }
      catch (ClassNotFoundException cnfe)
      {
         Class cl = primClasses.get(className);
         if (cl == null)
            throw cnfe;
         else
            return cl;
      }
   }

   protected Class<?> resolveProxyClass(String[] interfaces)
         throws IOException, ClassNotFoundException
   {
      // Load the interfaces from the thread context class loader
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      Class<?>[] ifaceClasses = new Class[interfaces.length];
      for (int i = 0; i < interfaces.length; i++)
      {
         ifaceClasses[i] = loader.loadClass(interfaces[i]);
      }

      return java.lang.reflect.Proxy.getProxyClass(loader, ifaceClasses);
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.property;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.jboss.util.ThrowableHandler;
import org.jboss.util.propertyeditor.PropertyEditors;

/**
 * Binds property values to class methods.
 *
 * @version <tt>$Revision$</tt>
 * @author  Jason Dillon
 */
public class MethodBoundPropertyListener
   extends BoundPropertyAdapter
{
   /** Property name which we are bound to */
   protected final String propertyName;

   /** Instance object that contains setter method */
   protected final Object instance;

   /** Property setter method */
   protected final Method setter;

   /** Property descriptor */
   protected final PropertyDescriptor descriptor;

   /**
    * Construct a MethodBoundPropertyListener.
    *
    * @param instance         Instance object that contains setter method.
    * @param propertyName     The name of the property which will be bound.
    * @param beanPropertyName The name of the property setter method.
    *
    * @throws PropertyException
    */
   public MethodBoundPropertyListener(final Object instance,
                                      final String propertyName,
                                      final String beanPropertyName)
   {
      this.instance = instance;
      this.propertyName = propertyName;

      try {
         descriptor = getPropertyDescriptor(beanPropertyName);
         if (descriptor == null) {
            throw new PropertyException
               ("missing method for: " + beanPropertyName);
         }

         setter = descriptor.getWriteMethod();
         if (setter == null) {
            throw new PropertyException
               ("missing setter method for: " + beanPropertyName);
         }
         try {
            setter.setAccessible(true);
         }
         catch (SecurityException e) {
            ThrowableHandler.add(e);
         }
      }
      catch (IntrospectionException e) {
         throw new PropertyException(e);
      }
   }

   /**
    * Get the <tt>PropertyDescriptor</tt> for the given bean property name.
    *
    * @param beanPropertyName    Bean property name.
    * @return                    <tt>PropertyDescriptor</tt>.
    */
   private PropertyDescriptor getPropertyDescriptor(final String beanPropertyName)
      throws IntrospectionException
   {
      Class<?> instanceType = instance.getClass();
      BeanInfo beanInfo = Introspector.getBeanInfo(instanceType);
      PropertyDescriptor descriptors[] = beanInfo.getPropertyDescriptors();
      PropertyDescriptor descriptor = null;

      for (int i=0; i<descriptors.length; i++) {
         if (descriptors[i].getName().equals(beanPropertyName)) {
            descriptor = descriptors[i];
            break;
         }
      }

      return descriptor;
   }

   /**
    * Construct a MethodBoundPropertyListener.
    *
    * @param instance         Instance object that contains setter method.
    * @param propertyName     The name of the property which will be bound.
    */
   public MethodBoundPropertyListener(final Object instance,
                                      final String propertyName)
   {
      this(instance, propertyName, propertyName);
   }

   /**
    * Get the property name which this listener is bound to.
    *
    * @return     Property name.
    */
   public final String getPropertyName() {
      return propertyName;
   }

   /**
    * Coerce and invoke the property setter method on the instance.
    *
    * @param value   Method value.
    *
    * @throws PropertyException     Failed to invoke setter method.
    */
   protected void invokeSetter(String value) {
      try {
         // coerce value to field type
         Class<?> type = descriptor.getPropertyType();
         PropertyEditor editor = PropertyEditors.findEditor(type);
         editor.setAsText(value);
         Object coerced = editor.getValue();
         // System.out.println("type: " + type);
         // System.out.println("coerced: " + coerced);

         // invoke the setter method
         setter.invoke(instance, new Object[] { coerced });
      }
      catch (InvocationTargetException e) {
         Throwable target = e.getTargetException();
         if (target instanceof PropertyException) {
            throw (PropertyException)target;
         }
         else {
            throw new PropertyException(target);
         }
      }
      catch (Exception e) {
         throw new PropertyException(e);
      }
   }

   /**
    * Notifies that a property has been added.
    *
    * @param event   Property event.
    */
   public void propertyAdded(final PropertyEvent event) {
      invokeSetter(event.getPropertyValue());
   }

   /**
    * Notifies that a property has changed.
    *
    * @param event   Property event.
    */
   public void propertyChanged(final PropertyEvent event) {
      invokeSetter(event.getPropertyValue());
   }

   /**
    * Notifies that this listener was bound to a property.
    *
    * @param map     PropertyMap which contains property bound to.
    */
   public void propertyBound(final PropertyMap map) {
      // only set the field if the map contains the property already
      if (map.containsProperty(propertyName)) {
         invokeSetter(map.getProperty(propertyName));
      }
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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.
 */

// Namespaces.java - Analyze namespace nodes in a DOM tree

package org.jboss.util.xml.catalog.helpers;

import org.w3c.dom.*;

/**
 * Static Namespace query methods.
 *
 *
This class defines a set of static methods that can be called
 * to analyze the namespace properties of DOM nodes.

 *
 * @author Norman Walsh
 * Norman.Walsh@Sun.COM
 *
 * @version 1.0
 */
public class Namespaces {
    /**
     * Returns the "prefix" part of a QName or the empty string (not
     * null) if the name has no prefix.
     *
     * @param element The QName of an element.
     * @return The prefix part of the element name.
     */
    public static String getPrefix(Element element) {
	String name = element.getTagName();
	String prefix = "";

	if (name.indexOf(':') > 0) {
	    prefix = name.substring(0, name.indexOf(':'));
	}

	return prefix;
    }

    /**
     * Returns the "localname" part of a QName, which is the whole
     * name if it has no prefix.
     *
     * @param element The QName of an element.
     * @return The local part of a QName.
     */
    public static String getLocalName(Element element) {
	String name = element.getTagName();

	if (name.indexOf(':') > 0) {
	    name = name.substring(name.indexOf(':')+1);
	}

	return name;
    }

    /**
     * Returns the namespace URI for the specified prefix at the
     * specified context node.
     *
     * @param node The context node.
     * @param prefix The prefix.
     * @return The namespace URI associated with the prefix, or
     * null if no namespace declaration exists for the prefix.
     */
    public static String getNamespaceURI(Node node, String prefix) {
	if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
	    return null;
	}

	if (prefix.equals("")) {
	    if (((Element) node).hasAttribute("xmlns")) {
		return ((Element) node).getAttribute("xmlns");
	    }
	} else {
	    String nsattr = "xmlns:" + prefix;
	    if (((Element) node).hasAttribute(nsattr)) {
		return ((Element) node).getAttribute(nsattr);
	    }
	}

	return getNamespaceURI(node.getParentNode(), prefix);
    }

    /**
     * Returns the namespace URI for the namespace to which the
     * element belongs.
     *
     * @param element The element.
     * @return The namespace URI associated with the namespace of the
     * element, or null if no namespace declaration exists for it.
     */
    public static String getNamespaceURI(Element element) {
	String prefix = getPrefix(element);
	return getNamespaceURI(element, prefix);
    }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.propertyeditor;

import java.beans.PropertyEditorSupport;

/**
 * A property editor for {@link Integer}.
 *
 * @author Scott.Stark@jboss.org
 * @version $Revision$
 */
public class LongEditor extends PropertyEditorSupport
{
   /**
    * Map the argument text into and Integer using Integer.valueOf.
    */
   public void setAsText(final String text)
   {
      if (PropertyEditors.isNull(text))
      {
         setValue(null);
         return;
      }
      Object newValue = Long.valueOf(text);
      setValue(newValue);
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.collection;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * CollectionsUtil.
 *
 * @author Adrian Brock
 * @version $Revision$
 */
@SuppressWarnings("unchecked")
public class CollectionsUtil
{
   /**
    * Create a list from an enumeration
    *
    * @param e the enumeration
    * @return the list
    */
   public static List list(Enumeration e)
   {
      ArrayList result = new ArrayList();
      while (e.hasMoreElements())
         result.add(e.nextElement());
      return result;
   }
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015, Red Hat, Inc., and individual contributors as indicated
 * by the @authors tag.
 *
 * 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 org.jboss.util.property;

import java.util.Properties;
import java.util.Map;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.IOException;

import org.jboss.util.NullArgumentException;

/**
 * Reads properties from one or more files.
 *
 * @version <tt>$Revision$</tt>
 * @author  Jason Dillon
 */
@SuppressWarnings("unchecked")
public class FilePropertyReader
   implements PropertyReader
{
   /** Array of filenames to load properties from */
   protected String[] filenames;

   /**
    * Construct a FilePropertyReader with an array of filenames
    * to read from.
    *
    * @param filenames  Filenames to load properties from
    */
   public FilePropertyReader(String[] filenames) {
      if (filenames == null)
         throw new NullArgumentException("filenames");

      this.filenames = filenames;
   }

   /**
    * Construct a FilePropertyReader with a single filename to read from.
    *
    * @param filename   Filename to load properties from
    */
   public FilePropertyReader(String filename) {
      this(new String[] { filename });
   }

   /**
    * Get an input stream for the given filename.
    *
    * @param filename   File name to get input stream for.
    * @return           Input stream for file.
    *
    * @throws IOException  Failed to get input stream for file.
    */
   protected InputStream getInputStream(String filename) throws IOException {
      File file = new File(filename);
      return new FileInputStream(file);
   }

   /**
    * Load properties from a file into a properties map.
    *
    * @param props      Properties map to load properties into.
    * @param filename   Filename to read properties from.
    *
    * @throws IOException              Failed to load properties from filename.
    * @throws IllegalArgumentException Filename is invalid.
    */
   protected void loadProperties(Properties props, String filename)
      throws IOException
   {
      if (filename == null)
         throw new NullArgumentException("filename");
      if (filename.equals(""))
         throw new IllegalArgumentException("filename");

      InputStream in = new BufferedInputStream(getInputStream(filename));
      props.load(in);
      in.close();
   }

   /**
    * Read properties from each specified filename
    *
    * @return  Read properties
    *
    * @throws PropertyException    Failed to read properties.
    * @throws IOException          I/O error while reading properties.
    */
   public Map readProperties()
      throws PropertyException, IOException
   {
      Properties props = new Properties();

      // load each specified property file
      for (int i=0; i<filenames.length; i++) {
         loadProperties(props, filenames[i]);
      }

      return props;
   }
}