/* $$ Clover has instrumented this file $$ */// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import javax.servlet.ServletContext;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.hivemind.Resource;
import org.apache.tapestry.event.ChangeObserver;
import org.apache.tapestry.event.ObservedChangeEvent;
import org.apache.tapestry.request.RequestContext;
import org.apache.tapestry.resource.ContextResource;
import org.apache.tapestry.spec.IComponentSpecification;
import org.apache.tapestry.util.AdaptorRegistry;
import org.apache.tapestry.util.StringSplitter;
/**
* A placeholder for a number of (static) methods that don't belong elsewhere, as well as a global
* location for static constants.
*
* @since 1.0.1
* @author Howard Lewis Ship
*/
public final class Tapestry
{public static com.cortexeb.tools.clover.d __CLOVER_33_0 = com.cortexeb.tools.clover.aq.getRecorder(new char[] {67,58,92,119,111,114,107,115,112,97,99,101,92,106,97,107,97,114,116,97,45,116,97,112,101,115,116,114,121,92,102,114,97,109,101,119,111,114,107,92,116,97,114,103,101,116,92,99,108,111,118,101,114,45,100,98},1097019445706L);
/**
* Name of a request attribute used with the {@link #TAGSUPPORT_SERVICE}service. The attribute
* defines the underlying service to for which a URL will be generated.
*
* @since 3.0
*/
public final static String TAG_SUPPORT_SERVICE_ATTRIBUTE = "org.apache.tapestry.tagsupport.service";
/**
* Name of a request attribute used with the {@link #TAGSUPPORT_SERVICE}service. The attribute
* defines the correct servlet path for the Tapestry application (which, for the odd-man-out
* TAGSUPPORT_SERVICE may not match HttpServletRequest.getServletPath() because of the use of an
* include.
*
* @since 3.0
*/
public final static String TAG_SUPPORT_SERVLET_PATH_ATTRIBUTE = "org.apache.tapestry.tagsupport.servlet-path";
/**
* Name of a request attribute used with the {@link #TAGSUPPORT_SERVICE}service. The attribute
* defines an array of objects to be converted into service parameters (i.e., for use with the
* {@link #EXTERNAL_SERVICE}).
*
* @since 3.0
*/
public final static String TAG_SUPPORT_PARAMETERS_ATTRIBUTE = "org.apache.tapestry.tagsupport.parameters";
/**
* Service used to support rendering of JSP tags. tagsupport is provided with a service and
* service parameters via request attributes and creates a URI from the result, which is output
* to the response.
*
* @since 3.0
*/
public static final String TAGSUPPORT_SERVICE = "tagsupport";
/**
* The name ("action") of a service that allows behavior to be associated with an
* {@link IAction}component, such as {@link org.apache.tapestry.link.ActionLink}or
* {@link org.apache.tapestry.form.Form}.
* <p>
* This service is used with actions that are tied to the dynamic state of the page, and which
* require a rewind of the page.
*/
public final static String ACTION_SERVICE = "action";
/**
* The name ("direct") of a service that allows stateless behavior for an {@link
* org.apache.tapestry.link.DirectLink} component.
* <p>
* This service rolls back the state of the page but doesn't rewind the the dynamic state of the
* page the was the action service does, which is more efficient but less powerful.
* <p>
* An array of String parameters may be included with the service URL; these will be made
* available to the {@link org.apache.tapestry.link.DirectLink}component's listener.
*/
public final static String DIRECT_SERVICE = "direct";
/**
* The name ("external") of a service that a allows {@link IExternalPage}to be selected.
* Associated with a {@link org.apache.tapestry.link.ExternalLink}component.
* <p>
* This service enables {@link IExternalPage}s to be accessed via a URL. External pages may be
* booked marked using their URL for future reference.
* <p>
* An array of Object parameters may be included with the service URL; these will be passed to
* the {@link IExternalPage#activateExternalPage(Object[], IRequestCycle)}method.
*/
public final static String EXTERNAL_SERVICE = "external";
/**
* The name ("page") of a service that allows a new page to be selected. Associated with a
* {@link org.apache.tapestry.link.PageLink}component.
* <p>
* The service requires a single parameter: the name of the target page.
*/
public final static String PAGE_SERVICE = "page";
/**
* The name ("home") of a service that jumps to the home page. A stand-in for when no service is
* provided, which is typically the entrypoint to the application.
*/
public final static String HOME_SERVICE = "home";
/**
* The name ("restart") of a service that invalidates the session and restarts the application.
* Typically used just to recover from an exception.
*/
public static final String RESTART_SERVICE = "restart";
/**
* The name ("asset") of a service used to access internal assets.
*/
public static final String ASSET_SERVICE = "asset";
/**
* The name ("reset") of a service used to clear cached template and specification data and
* remove all pooled pages. This is only used when debugging as a quick way to clear the out
* cached data, to allow updated versions of specifications and templates to be loaded (without
* stopping and restarting the servlet container).
* <p>
* This service is only available if the Java system property
* <code>org.apache.tapestry.enable-reset-service</code> is set to <code>true</code>.
*/
public static final String RESET_SERVICE = "reset";
/**
* Query parameter that identfies the service for the request.
*
* @since 1.0.3
*/
public static final String SERVICE_QUERY_PARAMETER_NAME = "service";
/**
* The query parameter for application specific parameters to the service (this is used with the
* direct service). Each of these values is encoded with
* {@link java.net.URLEncoder#encode(String)}before being added to the URL. Multiple values are
* handle by repeatedly establishing key/value pairs (this is a change from behavior in 2.1 and
* earlier).
*
* @since 1.0.3
*/
public static final String PARAMETERS_QUERY_PARAMETER_NAME = "sp";
/**
* Property name used to get the extension used for templates. This may be set in the page or
* component specification, or in the page (or component's) immediate container (library or
* application specification). Unlike most properties, value isn't inherited all the way up the
* chain. The default template extension is "html".
*
* @since 3.0
*/
public static final String TEMPLATE_EXTENSION_PROPERTY = "org.apache.tapestry.template-extension";
/**
* The default extension for templates, "html".
*
* @since 3.0
*/
public static final String DEFAULT_TEMPLATE_EXTENSION = "html";
/**
* The name of an {@link org.apache.tapestry.IRequestCycle}attribute in which the currently
* rendering {@link org.apache.tapestry.components.ILinkComponent}is stored. Link components do
* not nest.
*/
public static final String LINK_COMPONENT_ATTRIBUTE_NAME = "org.apache.tapestry.active-link-component";
/**
* Suffix appended to a parameter name to form the name of a property that stores the binding
* for the parameter.
*
* @since 3.0
*/
public static final String PARAMETER_PROPERTY_NAME_SUFFIX = "Binding";
/**
* Key used to obtain an extension from the application specification. The extension, if it
* exists, implements {@link org.apache.tapestry.request.IRequestDecoder}.
*
* @since 2.2
*/
public static final String REQUEST_DECODER_EXTENSION_NAME = "org.apache.tapestry.request-decoder";
/**
* Name of optional application extension for the multipart decoder used by the application. The
* extension must implement {@link org.apache.tapestry.multipart.IMultipartDecoder}(and is
* generally a configured instance of
* {@link org.apache.tapestry.multipart.DefaultMultipartDecoder}).
*
* @since 3.0
*/
public static final String MULTIPART_DECODER_EXTENSION_NAME = "org.apache.tapestry.multipart-decoder";
/**
* Method id used to check that {@link IPage#validate(IRequestCycle)}is invoked.
*
* @see #checkMethodInvocation(Object, String, Object)
* @since 3.0
*/
public static final String ABSTRACTPAGE_VALIDATE_METHOD_ID = "AbstractPage.validate()";
/**
* Method id used to check that {@link IPage#detach()}is invoked.
*
* @see #checkMethodInvocation(Object, String, Object)
* @since 3.0
*/
public static final String ABSTRACTPAGE_DETACH_METHOD_ID = "AbstractPage.detach()";
/**
* Regular expression defining a simple property name. Used by several different parsers. Simple
* property names match Java variable names; a leading letter (or underscore), followed by
* letters, numbers and underscores.
*
* @since 3.0
*/
public static final String SIMPLE_PROPERTY_NAME_PATTERN = "^_?[a-zA-Z]\\w*$";
/**
* Name of an application extension used as a factory for
* {@link org.apache.tapestry.engine.IMonitor}instances. The extension must implement
* {@link org.apache.tapestry.engine.IMonitorFactory}.
*
* @since 3.0
*/
public static final String MONITOR_FACTORY_EXTENSION_NAME = "org.apache.tapestry.monitor-factory";
/**
* Class name of an {@link ognl.TypeConverter}implementing class to use as a type converter for
* {@link org.apache.tapestry.binding.ExpressionBinding}
*/
public static final String OGNL_TYPE_CONVERTER = "org.apache.tapestry.ognl-type-converter";
/**
* Prevent instantiation.
*/
private Tapestry()
{try { __CLOVER_33_0.M[2701]++;
} finally { }}
/**
* The version of the framework; this is updated for major releases.
*/
public static final String VERSION = readVersion();
/**
* Contains strings loaded from TapestryStrings.properties.
*
* @since 1.0.8
*/
private static ResourceBundle _strings;
/**
* A {@link Map}that links Locale names (as in {@link Locale#toString()}to {@link Locale}
* instances. This prevents needless duplication of Locales.
*/
private static final Map _localeMap = new HashMap();
static
{
__CLOVER_33_0.S[10864]++;Locale[] locales = Locale.getAvailableLocales();
__CLOVER_33_0.S[10865]++;for (int i = 0; (((i < locales.length) && (++__CLOVER_33_0.CT[1881] != 0)) || (++__CLOVER_33_0.CF[1881] == 0)); i++){
{
__CLOVER_33_0.S[10866]++;_localeMap.put(locales[i].toString(), locales[i]);
}}
}
/**
* Used for tracking if a particular super-class method has been invoked.
*/
private static final ThreadLocal _invokedMethodIds = new ThreadLocal();
/**
* A {@link org.apache.tapestry.util.AdaptorRegistry}used to coerce arbitrary objects to
* boolean values.
*
* @see #evaluateBoolean(Object)
*/
private static final AdaptorRegistry _booleanAdaptors = new AdaptorRegistry();
private static abstract class BoolAdaptor
{
/**
* Implemented by subclasses to coerce an object to a boolean.
*/
public abstract boolean coerce(Object value);
}
private static class BooleanAdaptor extends BoolAdaptor
{
public boolean coerce(Object value)
{try { __CLOVER_33_0.M[2702]++;
__CLOVER_33_0.S[10867]++;Boolean b = (Boolean) value;
__CLOVER_33_0.S[10868]++;return b.booleanValue();
} finally { }}
}
private static class NumberAdaptor extends BoolAdaptor
{
public boolean coerce(Object value)
{try { __CLOVER_33_0.M[2703]++;
__CLOVER_33_0.S[10869]++;Number n = (Number) value;
__CLOVER_33_0.S[10870]++;return n.intValue() > 0;
} finally { }}
}
private static class CollectionAdaptor extends BoolAdaptor
{
public boolean coerce(Object value)
{try { __CLOVER_33_0.M[2704]++;
__CLOVER_33_0.S[10871]++;Collection c = (Collection) value;
__CLOVER_33_0.S[10872]++;return c.size() > 0;
} finally { }}
}
private static class StringAdaptor extends BoolAdaptor
{
public boolean coerce(Object value)
{try { __CLOVER_33_0.M[2705]++;
__CLOVER_33_0.S[10873]++;String s = (String) value;
__CLOVER_33_0.S[10874]++;if ((((s.length() == 0) && (++__CLOVER_33_0.CT[1882] != 0)) || (++__CLOVER_33_0.CF[1882] == 0))){
__CLOVER_33_0.S[10875]++;return false;}
__CLOVER_33_0.S[10876]++;String ts = s.trim();
__CLOVER_33_0.S[10877]++;if ((((ts.length() == 0) && (++__CLOVER_33_0.CT[1883] != 0)) || (++__CLOVER_33_0.CF[1883] == 0))){
__CLOVER_33_0.S[10878]++;return false;}
// Here probably Boolean.getBoolean(s) should be used,
// but we need the opposite check
__CLOVER_33_0.S[10879]++;if ((((ts.equalsIgnoreCase("false")) && (++__CLOVER_33_0.CT[1884] != 0)) || (++__CLOVER_33_0.CF[1884] == 0))){
__CLOVER_33_0.S[10880]++;return false;}
__CLOVER_33_0.S[10881]++;return true;
} finally { }}
}
static
{
__CLOVER_33_0.S[10882]++;_booleanAdaptors.register(Boolean.class, new BooleanAdaptor());
__CLOVER_33_0.S[10883]++;_booleanAdaptors.register(Number.class, new NumberAdaptor());
__CLOVER_33_0.S[10884]++;_booleanAdaptors.register(Collection.class, new CollectionAdaptor());
__CLOVER_33_0.S[10885]++;_booleanAdaptors.register(String.class, new StringAdaptor());
// Register a default, catch-all adaptor.
__CLOVER_33_0.S[10887]++;_booleanAdaptors.register(Object.class, new BoolAdaptor()
{
public boolean coerce(Object value)
{try { __CLOVER_33_0.M[2706]++;
__CLOVER_33_0.S[10886]++;return true;
} finally { }}
});
}
/**
* {@link AdaptorRegistry}used to extract an {@link Iterator}from an arbitrary object.
*/
private static AdaptorRegistry _iteratorAdaptors = new AdaptorRegistry();
private abstract static class IteratorAdaptor
{
/**
* Coeerces the object into an {@link Iterator}.
*/
abstract public Iterator coerce(Object value);
}
private static class DefaultIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2707]++;
__CLOVER_33_0.S[10888]++;return (Iterator) value;
} finally { }}
}
private static class CollectionIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2708]++;
__CLOVER_33_0.S[10889]++;Collection c = (Collection) value;
__CLOVER_33_0.S[10890]++;if ((((c.size() == 0) && (++__CLOVER_33_0.CT[1885] != 0)) || (++__CLOVER_33_0.CF[1885] == 0))){
__CLOVER_33_0.S[10891]++;return null;}
__CLOVER_33_0.S[10892]++;return c.iterator();
} finally { }}
}
private static class ObjectIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2709]++;
__CLOVER_33_0.S[10893]++;return Collections.singleton(value).iterator();
} finally { }}
}
private static class ObjectArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2710]++;
__CLOVER_33_0.S[10894]++;Object[] array = (Object[]) value;
__CLOVER_33_0.S[10895]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1886] != 0)) || (++__CLOVER_33_0.CF[1886] == 0))){
__CLOVER_33_0.S[10896]++;return null;}
__CLOVER_33_0.S[10897]++;return Arrays.asList(array).iterator();
} finally { }}
}
private static class BooleanArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2711]++;
__CLOVER_33_0.S[10898]++;boolean[] array = (boolean[]) value;
__CLOVER_33_0.S[10899]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1887] != 0)) || (++__CLOVER_33_0.CF[1887] == 0))){
__CLOVER_33_0.S[10900]++;return null;}
__CLOVER_33_0.S[10901]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10902]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1888] != 0)) || (++__CLOVER_33_0.CF[1888] == 0)); i++){
__CLOVER_33_0.S[10903]++;l.add((((array[i] ) && (++__CLOVER_33_0.CT[1889] != 0)) || (++__CLOVER_33_0.CF[1889] == 0))? Boolean.TRUE : Boolean.FALSE);}
__CLOVER_33_0.S[10904]++;return l.iterator();
} finally { }}
}
private static class ByteArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2712]++;
__CLOVER_33_0.S[10905]++;byte[] array = (byte[]) value;
__CLOVER_33_0.S[10906]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1890] != 0)) || (++__CLOVER_33_0.CF[1890] == 0))){
__CLOVER_33_0.S[10907]++;return null;}
__CLOVER_33_0.S[10908]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10909]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1891] != 0)) || (++__CLOVER_33_0.CF[1891] == 0)); i++){
__CLOVER_33_0.S[10910]++;l.add(new Byte(array[i]));}
__CLOVER_33_0.S[10911]++;return l.iterator();
} finally { }}
}
private static class CharArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2713]++;
__CLOVER_33_0.S[10912]++;char[] array = (char[]) value;
__CLOVER_33_0.S[10913]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1892] != 0)) || (++__CLOVER_33_0.CF[1892] == 0))){
__CLOVER_33_0.S[10914]++;return null;}
__CLOVER_33_0.S[10915]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10916]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1893] != 0)) || (++__CLOVER_33_0.CF[1893] == 0)); i++){
__CLOVER_33_0.S[10917]++;l.add(new Character(array[i]));}
__CLOVER_33_0.S[10918]++;return l.iterator();
} finally { }}
}
private static class ShortArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2714]++;
__CLOVER_33_0.S[10919]++;short[] array = (short[]) value;
__CLOVER_33_0.S[10920]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1894] != 0)) || (++__CLOVER_33_0.CF[1894] == 0))){
__CLOVER_33_0.S[10921]++;return null;}
__CLOVER_33_0.S[10922]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10923]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1895] != 0)) || (++__CLOVER_33_0.CF[1895] == 0)); i++){
__CLOVER_33_0.S[10924]++;l.add(new Short(array[i]));}
__CLOVER_33_0.S[10925]++;return l.iterator();
} finally { }}
}
private static class IntArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2715]++;
__CLOVER_33_0.S[10926]++;int[] array = (int[]) value;
__CLOVER_33_0.S[10927]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1896] != 0)) || (++__CLOVER_33_0.CF[1896] == 0))){
__CLOVER_33_0.S[10928]++;return null;}
__CLOVER_33_0.S[10929]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10930]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1897] != 0)) || (++__CLOVER_33_0.CF[1897] == 0)); i++){
__CLOVER_33_0.S[10931]++;l.add(new Integer(array[i]));}
__CLOVER_33_0.S[10932]++;return l.iterator();
} finally { }}
}
private static class LongArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2716]++;
__CLOVER_33_0.S[10933]++;long[] array = (long[]) value;
__CLOVER_33_0.S[10934]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1898] != 0)) || (++__CLOVER_33_0.CF[1898] == 0))){
__CLOVER_33_0.S[10935]++;return null;}
__CLOVER_33_0.S[10936]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10937]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1899] != 0)) || (++__CLOVER_33_0.CF[1899] == 0)); i++){
__CLOVER_33_0.S[10938]++;l.add(new Long(array[i]));}
__CLOVER_33_0.S[10939]++;return l.iterator();
} finally { }}
}
private static class FloatArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2717]++;
__CLOVER_33_0.S[10940]++;float[] array = (float[]) value;
__CLOVER_33_0.S[10941]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1900] != 0)) || (++__CLOVER_33_0.CF[1900] == 0))){
__CLOVER_33_0.S[10942]++;return null;}
__CLOVER_33_0.S[10943]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10944]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1901] != 0)) || (++__CLOVER_33_0.CF[1901] == 0)); i++){
__CLOVER_33_0.S[10945]++;l.add(new Float(array[i]));}
__CLOVER_33_0.S[10946]++;return l.iterator();
} finally { }}
}
private static class DoubleArrayIteratorAdaptor extends IteratorAdaptor
{
public Iterator coerce(Object value)
{try { __CLOVER_33_0.M[2718]++;
__CLOVER_33_0.S[10947]++;double[] array = (double[]) value;
__CLOVER_33_0.S[10948]++;if ((((array.length == 0) && (++__CLOVER_33_0.CT[1902] != 0)) || (++__CLOVER_33_0.CF[1902] == 0))){
__CLOVER_33_0.S[10949]++;return null;}
__CLOVER_33_0.S[10950]++;List l = new ArrayList(array.length);
__CLOVER_33_0.S[10951]++;for (int i = 0; (((i < array.length) && (++__CLOVER_33_0.CT[1903] != 0)) || (++__CLOVER_33_0.CF[1903] == 0)); i++){
__CLOVER_33_0.S[10952]++;l.add(new Double(array[i]));}
__CLOVER_33_0.S[10953]++;return l.iterator();
} finally { }}
}
static
{
__CLOVER_33_0.S[10954]++;_iteratorAdaptors.register(Iterator.class, new DefaultIteratorAdaptor());
__CLOVER_33_0.S[10955]++;_iteratorAdaptors.register(Collection.class, new CollectionIteratorAdaptor());
__CLOVER_33_0.S[10956]++;_iteratorAdaptors.register(Object.class, new ObjectIteratorAdaptor());
__CLOVER_33_0.S[10957]++;_iteratorAdaptors.register(Object[].class, new ObjectArrayIteratorAdaptor());
__CLOVER_33_0.S[10958]++;_iteratorAdaptors.register(boolean[].class, new BooleanArrayIteratorAdaptor());
__CLOVER_33_0.S[10959]++;_iteratorAdaptors.register(byte[].class, new ByteArrayIteratorAdaptor());
__CLOVER_33_0.S[10960]++;_iteratorAdaptors.register(char[].class, new CharArrayIteratorAdaptor());
__CLOVER_33_0.S[10961]++;_iteratorAdaptors.register(short[].class, new ShortArrayIteratorAdaptor());
__CLOVER_33_0.S[10962]++;_iteratorAdaptors.register(int[].class, new IntArrayIteratorAdaptor());
__CLOVER_33_0.S[10963]++;_iteratorAdaptors.register(long[].class, new LongArrayIteratorAdaptor());
__CLOVER_33_0.S[10964]++;_iteratorAdaptors.register(float[].class, new FloatArrayIteratorAdaptor());
__CLOVER_33_0.S[10965]++;_iteratorAdaptors.register(double[].class, new DoubleArrayIteratorAdaptor());
}
/**
* Copys all informal {@link IBinding bindings}from a source component to the destination
* component. Informal bindings are bindings for informal parameters. This will overwrite
* parameters (formal or informal) in the destination component if there is a naming conflict.
*/
public static void copyInformalBindings(IComponent source, IComponent destination)
{try { __CLOVER_33_0.M[2719]++;
__CLOVER_33_0.S[10966]++;Collection names = source.getBindingNames();
__CLOVER_33_0.S[10967]++;if ((((names == null) && (++__CLOVER_33_0.CT[1904] != 0)) || (++__CLOVER_33_0.CF[1904] == 0))){
__CLOVER_33_0.S[10968]++;return;}
__CLOVER_33_0.S[10969]++;IComponentSpecification specification = source.getSpecification();
__CLOVER_33_0.S[10970]++;Iterator i = names.iterator();
__CLOVER_33_0.S[10971]++;while ((((i.hasNext()) && (++__CLOVER_33_0.CT[1905] != 0)) || (++__CLOVER_33_0.CF[1905] == 0))){
{
__CLOVER_33_0.S[10972]++;String name = (String) i.next();
// If not a formal parameter, then copy it over.
__CLOVER_33_0.S[10973]++;if ((((specification.getParameter(name) == null) && (++__CLOVER_33_0.CT[1906] != 0)) || (++__CLOVER_33_0.CF[1906] == 0))){
{
__CLOVER_33_0.S[10974]++;IBinding binding = source.getBinding(name);
__CLOVER_33_0.S[10975]++;destination.setBinding(name, binding);
}}
}}
} finally { }}
/**
* Evaluates an object to determine its boolean value. <table border=1>
* <tr>
* <th>Class</th>
* <th>Test</th>
* </tr>
* <tr>
* <td>{@link Boolean}</td>
* <td>Self explanatory.</td>
* </tr>
* <tr>
* <td>{@link Number}</td>
* <td>True if non-zero, false otherwise.</td>
* </tr>
* <tr>
* <td>{@link Collection}</td>
* <td>True if contains any elements (non-zero size), false otherwise.</td>
* </tr>
* <tr>
* <td>{@link String}</td>
* <td>True if contains any non-whitespace characters, false otherwise.</td>
* </tr>
* <tr>
* <td>Any Object array type</td>
* <td>True if contains any elements (non-zero length), false otherwise.</td>
* <tr></table>
* <p>
* Any other non-null object evaluates to true.
*/
public static boolean evaluateBoolean(Object value)
{try { __CLOVER_33_0.M[2720]++;
__CLOVER_33_0.S[10976]++;if ((((value == null) && (++__CLOVER_33_0.CT[1907] != 0)) || (++__CLOVER_33_0.CF[1907] == 0))){
__CLOVER_33_0.S[10977]++;return false;}
__CLOVER_33_0.S[10978]++;Class valueClass = value.getClass();
__CLOVER_33_0.S[10979]++;if ((((valueClass.isArray()) && (++__CLOVER_33_0.CT[1908] != 0)) || (++__CLOVER_33_0.CF[1908] == 0))){
{
__CLOVER_33_0.S[10980]++;Object[] array = (Object[]) value;
__CLOVER_33_0.S[10981]++;return array.length > 0;
}}
__CLOVER_33_0.S[10982]++;BoolAdaptor adaptor = (BoolAdaptor) _booleanAdaptors.getAdaptor(valueClass);
__CLOVER_33_0.S[10983]++;return adaptor.coerce(value);
} finally { }}
/**
* Converts an Object into an {@link Iterator}, following some basic rules. <table border=1>
* <tr>
* <th>Input Class</th>
* <th>Result</th>
* </tr>
* <tr>
* <td>array</td>
* <td>Converted to a {@link List}and iterator returned. null returned if the array is empty.
* This works with both object arrays and arrays of scalars.</td>
* </tr>
* <tr>
* <td>{@link Iterator}</td>
* <td>Returned as-is.</td>
* <tr>
* <td>{@link Collection}</td>
* <td>Iterator returned, or null if the Collection is empty</td>
* </tr>
* <tr>
* <td>Any other</td>
* <td>{@link Iterator}for singleton collection returned</td>
* </tr>
* <tr>
* <td>null</td>
* <td>null returned</td>
* </tr>
* </table>
*/
public static Iterator coerceToIterator(Object value)
{try { __CLOVER_33_0.M[2721]++;
__CLOVER_33_0.S[10984]++;if ((((value == null) && (++__CLOVER_33_0.CT[1909] != 0)) || (++__CLOVER_33_0.CF[1909] == 0))){
__CLOVER_33_0.S[10985]++;return null;}
__CLOVER_33_0.S[10986]++;IteratorAdaptor adaptor = (IteratorAdaptor) _iteratorAdaptors.getAdaptor(value.getClass());
__CLOVER_33_0.S[10987]++;return adaptor.coerce(value);
} finally { }}
/**
* Gets the {@link Locale}for the given string, which is the result of
* {@link Locale#toString()}. If no such locale is already registered, a new instance is
* created, registered and returned.
*/
public static Locale getLocale(String s)
{try { __CLOVER_33_0.M[2722]++;
__CLOVER_33_0.S[10988]++;Locale result = null;
__CLOVER_33_0.S[10989]++;synchronized (_localeMap)
{
__CLOVER_33_0.S[10990]++;result = (Locale) _localeMap.get(s);
}
__CLOVER_33_0.S[10991]++;if ((((result == null) && (++__CLOVER_33_0.CT[1910] != 0)) || (++__CLOVER_33_0.CF[1910] == 0))){
{
__CLOVER_33_0.S[10992]++;StringSplitter splitter = new StringSplitter('_');
__CLOVER_33_0.S[10993]++;String[] terms = splitter.splitToArray(s);
__CLOVER_33_0.S[10994]++;switch (terms.length)
{
case 1:
__CLOVER_33_0.S[10995]++;result = new Locale(terms[0], "");
__CLOVER_33_0.S[10996]++;break;
case 2:
__CLOVER_33_0.S[10997]++;result = new Locale(terms[0], terms[1]);
__CLOVER_33_0.S[10998]++;break;
case 3:
__CLOVER_33_0.S[10999]++;result = new Locale(terms[0], terms[1], terms[2]);
__CLOVER_33_0.S[11000]++;break;
default:
__CLOVER_33_0.S[11001]++;throw new IllegalArgumentException("Unable to convert '" + s + "' to a Locale.");
}
__CLOVER_33_0.S[11002]++;synchronized (_localeMap)
{
__CLOVER_33_0.S[11003]++;_localeMap.put(s, result);
}
}}
__CLOVER_33_0.S[11004]++;return result;
} finally { }}
/**
* Closes the stream (if not null), ignoring any {@link IOException}thrown.
*
* @since 1.0.2
*/
public static void close(InputStream stream)
{try { __CLOVER_33_0.M[2723]++;
__CLOVER_33_0.S[11005]++;if ((((stream != null) && (++__CLOVER_33_0.CT[1911] != 0)) || (++__CLOVER_33_0.CF[1911] == 0))){
{
__CLOVER_33_0.S[11006]++;try
{
__CLOVER_33_0.S[11007]++;stream.close();
}
catch (IOException ex)
{
// Ignore.
}
}}
} finally { }}
/**
* Gets a string from the TapestryStrings resource bundle. The string in the bundle is treated
* as a pattern for {@link MessageFormat#format(java.lang.String, java.lang.Object[])}.
*
* @since 1.0.8
*/
public static String format(String key, Object[] args)
{try { __CLOVER_33_0.M[2724]++;
__CLOVER_33_0.S[11008]++;if ((((_strings == null) && (++__CLOVER_33_0.CT[1912] != 0)) || (++__CLOVER_33_0.CF[1912] == 0))){
__CLOVER_33_0.S[11009]++;_strings = ResourceBundle.getBundle("org.apache.tapestry.TapestryStrings");}
__CLOVER_33_0.S[11010]++;String pattern = _strings.getString(key);
__CLOVER_33_0.S[11011]++;if ((((args == null) && (++__CLOVER_33_0.CT[1913] != 0)) || (++__CLOVER_33_0.CF[1913] == 0))){
__CLOVER_33_0.S[11012]++;return pattern;}
__CLOVER_33_0.S[11013]++;return MessageFormat.format(pattern, args);
} finally { }}
/**
* Convienience method for invoking {@link #format(String, Object[])}.
*
* @since 3.0
*/
public static String getMessage(String key)
{try { __CLOVER_33_0.M[2725]++;
__CLOVER_33_0.S[11014]++;return format(key, null);
} finally { }}
/**
* Convienience method for invoking {@link #format(String, Object[])}.
*
* @since 3.0
*/
public static String format(String key, Object arg)
{try { __CLOVER_33_0.M[2726]++;
__CLOVER_33_0.S[11015]++;return format(key, new Object[]
{ arg });
} finally { }}
/**
* Convienience method for invoking {@link #format(String, Object[])}.
*
* @since 3.0
*/
public static String format(String key, Object arg1, Object arg2)
{try { __CLOVER_33_0.M[2727]++;
__CLOVER_33_0.S[11016]++;return format(key, new Object[]
{ arg1, arg2 });
} finally { }}
/**
* Convienience method for invoking {@link #format(String, Object[])}.
*
* @since 3.0
*/
public static String format(String key, Object arg1, Object arg2, Object arg3)
{try { __CLOVER_33_0.M[2728]++;
__CLOVER_33_0.S[11017]++;return format(key, new Object[]
{ arg1, arg2, arg3 });
} finally { }}
private static final String UNKNOWN_VERSION = "Unknown";
/**
* Invoked when the class is initialized to read the current version file.
*/
private static final String readVersion()
{try { __CLOVER_33_0.M[2729]++;
__CLOVER_33_0.S[11018]++;Properties props = new Properties();
__CLOVER_33_0.S[11019]++;try
{
__CLOVER_33_0.S[11020]++;InputStream in = Tapestry.class.getResourceAsStream("version.properties");
__CLOVER_33_0.S[11021]++;if ((((in == null) && (++__CLOVER_33_0.CT[1914] != 0)) || (++__CLOVER_33_0.CF[1914] == 0))){
__CLOVER_33_0.S[11022]++;return UNKNOWN_VERSION;}
__CLOVER_33_0.S[11023]++;props.load(in);
__CLOVER_33_0.S[11024]++;in.close();
__CLOVER_33_0.S[11025]++;return props.getProperty("project.version", UNKNOWN_VERSION);
}
catch (IOException ex)
{
__CLOVER_33_0.S[11026]++;return UNKNOWN_VERSION;
}
} finally { }}
/**
* Returns the size of a collection, or zero if the collection is null.
*
* @since 2.2
*/
public static int size(Collection c)
{try { __CLOVER_33_0.M[2730]++;
__CLOVER_33_0.S[11027]++;if ((((c == null) && (++__CLOVER_33_0.CT[1915] != 0)) || (++__CLOVER_33_0.CF[1915] == 0))){
__CLOVER_33_0.S[11028]++;return 0;}
__CLOVER_33_0.S[11029]++;return c.size();
} finally { }}
/**
* Returns the length of the array, or 0 if the array is null.
*
* @since 2.2
*/
public static int size(Object[] array)
{try { __CLOVER_33_0.M[2731]++;
__CLOVER_33_0.S[11030]++;if ((((array == null) && (++__CLOVER_33_0.CT[1916] != 0)) || (++__CLOVER_33_0.CF[1916] == 0))){
__CLOVER_33_0.S[11031]++;return 0;}
__CLOVER_33_0.S[11032]++;return array.length;
} finally { }}
/**
* Returns true if the Map is null or empty.
*
* @since 3.0
*/
public static boolean isEmpty(Map map)
{try { __CLOVER_33_0.M[2732]++;
__CLOVER_33_0.S[11033]++;return map == null || map.isEmpty();
} finally { }}
/**
* Returns true if the Collection is null or empty.
*
* @since 3.0
*/
public static boolean isEmpty(Collection c)
{try { __CLOVER_33_0.M[2733]++;
__CLOVER_33_0.S[11034]++;return c == null || c.isEmpty();
} finally { }}
/**
* Converts a {@link Map}to an even-sized array of key/value pairs. This may be useful when
* using a Map as service parameters (with {@link org.apache.tapestry.link.DirectLink}.
* Assuming the keys and values are simple objects (String, Boolean, Integer, etc.), then the
* representation as an array will encode more efficiently (via
* {@link org.apache.tapestry.util.io.DataSqueezerImpl}than serializing the Map and its
* contents.
*
* @return the array of keys and values, or null if the input Map is null or empty
* @since 2.2
*/
public static Object[] convertMapToArray(Map map)
{try { __CLOVER_33_0.M[2734]++;
__CLOVER_33_0.S[11035]++;if ((((isEmpty(map)) && (++__CLOVER_33_0.CT[1917] != 0)) || (++__CLOVER_33_0.CF[1917] == 0))){
__CLOVER_33_0.S[11036]++;return null;}
__CLOVER_33_0.S[11037]++;Set entries = map.entrySet();
__CLOVER_33_0.S[11038]++;Object[] result = new Object[2 * entries.size()];
__CLOVER_33_0.S[11039]++;int x = 0;
__CLOVER_33_0.S[11040]++;Iterator i = entries.iterator();
__CLOVER_33_0.S[11041]++;while ((((i.hasNext()) && (++__CLOVER_33_0.CT[1918] != 0)) || (++__CLOVER_33_0.CF[1918] == 0))){
{
__CLOVER_33_0.S[11042]++;Map.Entry entry = (Map.Entry) i.next();
__CLOVER_33_0.S[11043]++;result[x++] = entry.getKey();
__CLOVER_33_0.S[11044]++;result[x++] = entry.getValue();
}}
__CLOVER_33_0.S[11045]++;return result;
} finally { }}
/**
* Converts an even-sized array of objects back into a {@link Map}.
*
* @see #convertMapToArray(Map)
* @return a Map, or null if the array is null or empty
* @since 2.2
*/
public static Map convertArrayToMap(Object[] array)
{try { __CLOVER_33_0.M[2735]++;
__CLOVER_33_0.S[11046]++;if ((((array == null || array.length == 0) && (++__CLOVER_33_0.CT[1919] != 0)) || (++__CLOVER_33_0.CF[1919] == 0))){
__CLOVER_33_0.S[11047]++;return null;}
__CLOVER_33_0.S[11048]++;if ((((array.length % 2 != 0) && (++__CLOVER_33_0.CT[1920] != 0)) || (++__CLOVER_33_0.CF[1920] == 0))){
__CLOVER_33_0.S[11049]++;throw new IllegalArgumentException(getMessage("Tapestry.even-sized-array"));}
__CLOVER_33_0.S[11050]++;Map result = new HashMap();
__CLOVER_33_0.S[11051]++;int x = 0;
__CLOVER_33_0.S[11052]++;while ((((x < array.length) && (++__CLOVER_33_0.CT[1921] != 0)) || (++__CLOVER_33_0.CF[1921] == 0))){
{
__CLOVER_33_0.S[11053]++;Object key = array[x++];
__CLOVER_33_0.S[11054]++;Object value = array[x++];
__CLOVER_33_0.S[11055]++;result.put(key, value);
}}
__CLOVER_33_0.S[11056]++;return result;
} finally { }}
/**
* Returns the application root location, which is in the {@link javax.servlet.ServletContext},
* based on the {@link javax.servlet.http.HttpServletRequest#getServletPath() servlet path}.
*
* @since 3.0
*/
public static Resource getApplicationRootLocation(IRequestCycle cycle)
{try { __CLOVER_33_0.M[2736]++;
__CLOVER_33_0.S[11057]++;RequestContext context = cycle.getRequestContext();
__CLOVER_33_0.S[11058]++;ServletContext servletContext = context.getServlet().getServletContext();
__CLOVER_33_0.S[11059]++;String servletPath = context.getRequest().getServletPath();
// Could strip off the servlet name (i.e., "app" in "/app") but
// there's no need.
__CLOVER_33_0.S[11060]++;return new ContextResource(servletContext, servletPath);
} finally { }}
/**
* Given a Class, creates a presentable name for the class, even if the class is a scalar type
* or Array type.
*
* @since 3.0
*/
public static String getClassName(Class subject)
{try { __CLOVER_33_0.M[2737]++;
__CLOVER_33_0.S[11061]++;if ((((subject.isArray()) && (++__CLOVER_33_0.CT[1922] != 0)) || (++__CLOVER_33_0.CF[1922] == 0))){
__CLOVER_33_0.S[11062]++;return getClassName(subject.getComponentType()) + "[]";}
__CLOVER_33_0.S[11063]++;return subject.getName();
} finally { }}
/**
* Creates an exception indicating the binding value is null.
*
* @since 3.0
*/
public static BindingException createNullBindingException(IBinding binding)
{try { __CLOVER_33_0.M[2738]++;
__CLOVER_33_0.S[11064]++;return new BindingException(getMessage("null-value-for-binding"), binding);
} finally { }}
/** @since 3.0 * */
public static ApplicationRuntimeException createNoSuchComponentException(IComponent component,
String id, Location location)
{try { __CLOVER_33_0.M[2739]++;
__CLOVER_33_0.S[11065]++;return new ApplicationRuntimeException(format("no-such-component", component
.getExtendedId(), id), component, location, null);
} finally { }}
/** @since 3.0 * */
public static BindingException createRequiredParameterException(IComponent component,
String parameterName)
{try { __CLOVER_33_0.M[2740]++;
__CLOVER_33_0.S[11066]++;return new BindingException(format("required-parameter", parameterName, component
.getExtendedId()), component, null, component.getBinding(parameterName), null);
} finally { }}
/** @since 3.0 * */
public static ApplicationRuntimeException createRenderOnlyPropertyException(
IComponent component, String propertyName)
{try { __CLOVER_33_0.M[2741]++;
__CLOVER_33_0.S[11067]++;return new ApplicationRuntimeException(format(
"render-only-property",
propertyName,
component.getExtendedId()), component, null, null);
} finally { }}
/**
* Clears the list of method invocations.
*
* @see #checkMethodInvocation(Object, String, Object)
* @since 3.0
*/
public static void clearMethodInvocations()
{try { __CLOVER_33_0.M[2742]++;
__CLOVER_33_0.S[11068]++;_invokedMethodIds.set(null);
} finally { }}
/**
* Adds a method invocation to the list of invocations. This is done in a super-class
* implementations.
*
* @see #checkMethodInvocation(Object, String, Object)
* @since 3.0
*/
public static void addMethodInvocation(Object methodId)
{try { __CLOVER_33_0.M[2743]++;
__CLOVER_33_0.S[11069]++;List methodIds = (List) _invokedMethodIds.get();
__CLOVER_33_0.S[11070]++;if ((((methodIds == null) && (++__CLOVER_33_0.CT[1923] != 0)) || (++__CLOVER_33_0.CF[1923] == 0))){
{
__CLOVER_33_0.S[11071]++;methodIds = new ArrayList();
__CLOVER_33_0.S[11072]++;_invokedMethodIds.set(methodIds);
}}
__CLOVER_33_0.S[11073]++;methodIds.add(methodId);
} finally { }}
/**
* Checks to see if a particular method has been invoked. The method is identified by a methodId
* (usually a String). The methodName and object are used to create an error message.
* <p>
* The caller should invoke {@link #clearMethodInvocations()}, then invoke a method on the
* object. The super-class implementation should invoke {@link #addMethodInvocation(Object)}to
* indicate that it was, in fact, invoked. The caller then invokes this method to vlaidate that
* the super-class implementation was invoked.
* <p>
* The list of method invocations is stored in a {@link ThreadLocal}variable.
*
* @since 3.0
*/
public static void checkMethodInvocation(Object methodId, String methodName, Object object)
{try { __CLOVER_33_0.M[2744]++;
__CLOVER_33_0.S[11074]++;List methodIds = (List) _invokedMethodIds.get();
__CLOVER_33_0.S[11075]++;if ((((methodIds != null && methodIds.contains(methodId)) && (++__CLOVER_33_0.CT[1924] != 0)) || (++__CLOVER_33_0.CF[1924] == 0))){
__CLOVER_33_0.S[11076]++;return;}
__CLOVER_33_0.S[11077]++;throw new ApplicationRuntimeException(Tapestry.format(
"Tapestry.missing-method-invocation",
object.getClass().getName(),
methodName));
} finally { }}
/**
* Method used by pages and components to send notifications about property changes.
*
* @param component
* the component containing the property
* @param propertyName
* the name of the property which changed
* @param newValue
* the new value for the property
* @since 3.0
*/
public static void fireObservedChange(IComponent component, String propertyName, Object newValue)
{try { __CLOVER_33_0.M[2745]++;
__CLOVER_33_0.S[11078]++;ChangeObserver observer = component.getPage().getChangeObserver();
__CLOVER_33_0.S[11079]++;if ((((observer == null) && (++__CLOVER_33_0.CT[1925] != 0)) || (++__CLOVER_33_0.CF[1925] == 0))){
__CLOVER_33_0.S[11080]++;return;}
__CLOVER_33_0.S[11081]++;ObservedChangeEvent event = new ObservedChangeEvent(component, propertyName, newValue);
__CLOVER_33_0.S[11082]++;observer.observeChange(event);
} finally { }}
/**
* Returns true if the input is null or contains only whitespace.
* <p>
* Note: Yes, you'd think we'd use <code>StringUtils</code>, but with the change in names and
* behavior between releases, it is smarter to just implement our own little method!
*
* @since 3.0
*/
public static boolean isBlank(String input)
{try { __CLOVER_33_0.M[2746]++;
__CLOVER_33_0.S[11083]++;if ((((input == null || input.length() == 0) && (++__CLOVER_33_0.CT[1926] != 0)) || (++__CLOVER_33_0.CF[1926] == 0))){
__CLOVER_33_0.S[11084]++;return true;}
__CLOVER_33_0.S[11085]++;return input.trim().length() == 0;
} finally { }}
/**
* Returns true if the input is not null and not empty (or only whitespace).
*
* @since 3.0
*/
public static boolean isNonBlank(String input)
{try { __CLOVER_33_0.M[2747]++;
__CLOVER_33_0.S[11086]++;return !isBlank(input);
} finally { }}
/**
* Defensive programming: check for null parameter where it is not acceptible.
*/
public static void notNull(Object parameter, String parameterName)
{try { __CLOVER_33_0.M[2748]++;
__CLOVER_33_0.S[11087]++;if ((((parameter == null) && (++__CLOVER_33_0.CT[1927] != 0)) || (++__CLOVER_33_0.CF[1927] == 0))){
__CLOVER_33_0.S[11088]++;throw new NullPointerException(TapestryMessages.paramNotNull(parameterName));}
} finally { }}
}