001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.hivemind;
016
017import java.util.Collection;
018
019/**
020 * Static utility class for HiveMind.
021 * 
022 * @author Howard Lewis Ship
023 */
024public final class HiveMind
025{
026    /**
027     * The full id of the {@link org.apache.hivemind.service.ThreadEventNotifier} service.
028     */
029    public static final String THREAD_EVENT_NOTIFIER_SERVICE = "hivemind.ThreadEventNotifier";
030
031    /**
032     * The full id of the {@link org.apache.hivemind.service.ThreadLocale} service.
033     * 
034     * @since 1.1
035     */
036
037    public static final String THREAD_LOCALE_SERVICE = "hivemind.ThreadLocale";
038
039    /**
040     * The full id of the {@link org.apache.hivemind.service.InterfaceSynthesizer} service.
041     * 
042     * @since 1.1
043     */
044
045    public static final String INTERFACE_SYNTHESIZER_SERVICE = "hivemind.InterfaceSynthesizer";
046
047    /**
048     * An object used to synchronize access to {@link java.beans.Introspector} (which is not fully
049     * threadsafe).
050     * 
051     * @since 1.1
052     */
053
054    public static final Object INTROSPECTOR_MUTEX = new Object();
055
056    private HiveMind()
057    {
058        // Prevent instantiation
059    }
060
061    public static ApplicationRuntimeException createRegistryShutdownException()
062    {
063        return new ApplicationRuntimeException(HiveMindMessages.registryShutdown());
064    }
065
066    /**
067     * Selects the first {@link Location} in an array of objects. Skips over nulls. The objects may
068     * be instances of Location or {@link Locatable}. May return null if no Location can be found.
069     */
070
071    public static Location findLocation(Object[] locations)
072    {
073        for (int i = 0; i < locations.length; i++)
074        {
075            Object location = locations[i];
076
077            Location result = getLocation(location);
078
079            if (result != null)
080                return result;
081
082        }
083
084        return null;
085    }
086
087    /**
088     * Extracts a location from an object, checking to see if it implement {@link Location} or
089     * {@link Locatable}.
090     * 
091     * @return the Location, or null if it can't be found
092     */
093    public static Location getLocation(Object object)
094    {
095        if (object == null)
096            return null;
097
098        if (object instanceof Location)
099            return (Location) object;
100
101        if (object instanceof Locatable)
102        {
103            Locatable locatable = (Locatable) object;
104
105            return locatable.getLocation();
106        }
107
108        return null;
109    }
110
111    /**
112     * Invokes {@link #getLocation(Object)}, then translate the result to a string value, or
113     * "unknown location" if null.
114     */
115    public static String getLocationString(Object object)
116    {
117        Location l = getLocation(object);
118
119        if (l != null)
120            return l.toString();
121
122        return HiveMindMessages.unknownLocation();
123    }
124
125    /**
126     * Returns true if the string is null, empty, or contains only whitespace.
127     * <p>
128     * The commons-lang library provides a version of this, but the naming and behavior changed
129     * between 1.0 and 2.0, which causes some dependency issues.
130     */
131    public static boolean isBlank(String string)
132    {
133        if (string == null || string.length() == 0)
134            return true;
135
136        if (string.trim().length() == 0)
137            return true;
138
139        return false;
140    }
141
142    /**
143     * As with {@link #isBlank(String)}, but inverts the response.
144     */
145    public static boolean isNonBlank(String string)
146    {
147        return !isBlank(string);
148    }
149
150    /**
151     * Updates the location of an object, if the object implements {@link LocationHolder}.
152     * 
153     * @param holder
154     *            the object to be updated
155     * @param location
156     *            the location to assign to the holder object
157     */
158    public static void setLocation(Object holder, Location location)
159    {
160        if (holder != null && holder instanceof LocationHolder)
161        {
162            LocationHolder lh = (LocationHolder) holder;
163
164            lh.setLocation(location);
165        }
166    }
167
168    /**
169     * Returns true if the Collection is null or empty.
170     */
171    public static boolean isEmpty(Collection c)
172    {
173        return c == null || c.isEmpty();
174    }
175}