1 /*
   2  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.beans.finder;
  26 
  27 /**
  28  * This is utility class that provides basic functionality
  29  * to find an auxiliary class for a JavaBean specified by its type.
  30  *
  31  * @since 1.7
  32  *
  33  * @author Sergey A. Malenkov
  34  */
  35 class InstanceFinder<T> {
  36 
  37     private static final String[] EMPTY = { };
  38 
  39     private final Class<? extends T> type;
  40     private final boolean allow;
  41     private final String suffix;
  42     private volatile String[] packages;
  43 
  44     InstanceFinder(Class<? extends T> type, boolean allow, String suffix, String... packages) {
  45         this.type = type;
  46         this.allow = allow;
  47         this.suffix = suffix;
  48         this.packages = packages.clone();
  49     }
  50 
  51     public String[] getPackages() {
  52         return this.packages.clone();
  53     }
  54 
  55     public void setPackages(String... packages) {
  56         this.packages = (packages != null) && (packages.length > 0)
  57                 ? packages.clone()
  58                 : EMPTY;
  59     }
  60 
  61     public T find(Class<?> type) {
  62         if (type == null) {
  63             return null;
  64         }
  65         String name = type.getName() + this.suffix;
  66         T object = instantiate(type, name);
  67         if (object != null) {
  68             return object;
  69         }
  70         if (this.allow) {
  71             object = instantiate(type, null);
  72             if (object != null) {
  73                 return object;
  74             }
  75         }
  76         int index = name.lastIndexOf('.') + 1;
  77         if (index > 0) {
  78             name = name.substring(index);
  79         }
  80         for (String prefix : this.packages) {
  81             object = instantiate(type, prefix, name);
  82             if (object != null) {
  83                 return object;
  84             }
  85         }
  86         return null;
  87     }
  88 
  89     protected T instantiate(Class<?> type, String name) {
  90         if (type != null) {
  91             try {
  92                 if (name != null) {
  93                     type = ClassFinder.findClass(name, type.getClassLoader());
  94                 }
  95                 if (this.type.isAssignableFrom(type)) {
  96                     return (T) type.newInstance();
  97                 }
  98             }
  99             catch (Exception exception) {
 100                 // ignore any exceptions
 101             }
 102         }
 103         return null;
 104     }
 105 
 106     protected T instantiate(Class<?> type, String prefix, String name) {
 107         return instantiate(type, prefix + '.' + name);
 108     }
 109 }