diff --git a/core/src/main/java/org/demoiselle/jee/core/annotation/Ignore.java b/core/src/main/java/org/demoiselle/jee/core/annotation/Ignore.java
new file mode 100644
index 0000000..4c793da
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/annotation/Ignore.java
@@ -0,0 +1,56 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.jee.core.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ *
Used in fields of classes annotated with {@link org.demoiselle.configuration.Configuration}
+ * to indicate that the system should ignore this field when population the new configuration
+ * instance with values extracted from the source file.
+ *
+ * @see org.demoiselle.configuration.Configuration
+ * @author SERPRO
+ */
+@Target(FIELD)
+@Retention(RUNTIME)
+public @interface Ignore {
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/annotation/Name.java b/core/src/main/java/org/demoiselle/jee/core/annotation/Name.java
new file mode 100644
index 0000000..8e93aaa
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/annotation/Name.java
@@ -0,0 +1,98 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.jee.core.annotation;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Named;
+import javax.inject.Qualifier;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ *
+ * String based non-binding qualifier.
+ *
+ *
+ *
+ * This annotation is used to qualify beans using an user defined String. {@link javax.enterprise.inject.Produces}
+ * methods can then read this string and use it to customize the bean creation process.
+ *
+ *
+ *
+ * The {@link #value()} attribute is non-binding (contrary to {@link Named#value()}, meaning multiple classes
+ * qualified with this annotation, even with different values, will be considered the same candidate for
+ * injection points. To avoid ambiguous resolutions and select which candidate to choose usually you'll need a
+ * producer method to read the string and select the best fitted candidate.
+ *
+ *
+ *
+ * The framework classes qualified with this annotation already have such producers and the accepted values for
+ * this annotation will be detailed in their respective documentations.
+ *
+ *
+ *
+ * @author SERPRO
+ *
+ * @see org.demoiselle.util.ResourceBundle
+ * @see org.demoiselle.internal.producer.ResourceBundleProducer#create(InjectionPoint)
+ * @see org.demoiselle.internal.producer.LoggerProducer#createNamed(InjectionPoint)
+ */
+@Qualifier
+@Inherited
+@Retention(RUNTIME)
+@Target({ TYPE, FIELD, METHOD, PARAMETER })
+public @interface Name {
+
+ /**
+ *
+ * Specifies a name to access a custom configuration that will change how the annotated bean works.
+ *
+ *
+ * This attribute is nonbinding so you can use the {@link Name} annotation to create {@linkplain javax.enterprise.inject.Produces}
+ * methods or fields and have only one producer that works with all injection points no matter the value of this attribute.
+ *
+ * @return Name of custom settings to personalize how the annotated bean works.
+ */
+ @Nonbinding
+ String value() default "";
+
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/annotation/Priority.java b/core/src/main/java/org/demoiselle/jee/core/annotation/Priority.java
new file mode 100644
index 0000000..e1d04ac
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/annotation/Priority.java
@@ -0,0 +1,96 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.jee.core.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ *
+ * Used to prioritize some execution flow, as methods annotated with @startup or @shutdown,
+ * or some interface implementation.
+ *
+ *
+ * @author SERPRO
+ */
+@Target({ TYPE, METHOD })
+@Retention(RUNTIME)
+public @interface Priority {
+
+ /**
+ * Most important priority value.
+ */
+ static int MAX_PRIORITY = Integer.MIN_VALUE;
+
+ /**
+ * Less important priority value.
+ */
+ static int MIN_PRIORITY = Integer.MAX_VALUE;
+
+ /**
+ * Less important priority value.
+ */
+ static int L1_PRIORITY = MIN_PRIORITY;
+
+ /**
+ * Higher priority than L1_PRIORITY
+ */
+ static int L2_PRIORITY = L1_PRIORITY - 100;
+
+ /**
+ * Higher priority than L2_PRIORITY
+ */
+ static int L3_PRIORITY = L2_PRIORITY - 100;
+
+ /**
+ * Higher priority than L3_PRIORITY
+ */
+ static int L4_PRIORITY = L3_PRIORITY - 100;
+
+ /**
+ *
+ * An integer value defines the priority order. The lower the value, the greater priority.
+ *
+ *
+ * @return Priority value, lower values have higher priority.
+ */
+ int value();
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/annotation/Strategy.java b/core/src/main/java/org/demoiselle/jee/core/annotation/Strategy.java
new file mode 100644
index 0000000..335692f
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/annotation/Strategy.java
@@ -0,0 +1,83 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.jee.core.annotation;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ *
+ *
+ * This literal marks a bean to be selected at runtime based on a priority system.
+ * The user qualifies the injection point with this literal and then at runtime
+ * the CDI engine will circle through all candidate subtypes to be injected
+ * that are annotated with {@link Priority}. If there is only one subtype with the
+ * highest priority then this one will be selected to be injected.
+ *
+ *
+ *
+ * This allows users to plug in libraries with new candidates and have them be selected
+ * if their priority values are higher than the default values already present. One example
+ * is the {@link org.demoiselle.security.Authorizer} type, the framework has a {@link org.demoiselle.internal.implementation.DefaultAuthorizer}
+ * with {@link Priority#L1_PRIORITY the lowest priority} but the user can add libraries with new
+ * implementations of {@link org.demoiselle.security.Authorizer} annotated with higher priorities, the code will
+ * then automatically select these new implementations with no extra configuration.
+ *
+ *
+ *
+ * This annotation must be used with supported types. Usually this involves creating {@link javax.enterprise.inject.Produces} CDI
+ * producer methods that will select the correct strategy. To create your own producer
+ * methods that support strategy selection, use the utility {@linkplain org.demoiselle.internal.producer.StrategySelector}.
+ *
+ *
+ * @author SERPRO
+ */
+@Qualifier
+@Inherited
+@Retention(RUNTIME)
+@Target({ TYPE, FIELD, METHOD, PARAMETER })
+public @interface Strategy {
+
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/internal/producer/ResourceBundleProducer.java b/core/src/main/java/org/demoiselle/jee/core/internal/producer/ResourceBundleProducer.java
new file mode 100644
index 0000000..8176701
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/internal/producer/ResourceBundleProducer.java
@@ -0,0 +1,72 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.demoiselle.jee.core.internal.producer;
+
+import java.io.Serializable;
+import java.util.Locale;
+import org.demoiselle.jee.core.util.ResourceBundle;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.CDI;
+import javax.enterprise.inject.spi.InjectionPoint;
+import org.demoiselle.jee.core.annotation.Name;
+import org.demoiselle.util.CDIUtils;
+
+/**
+ *
+ * @author 70744416353
+ */
+@Dependent
+public class ResourceBundleProducer implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Default
+ @Produces
+ public ResourceBundle createDefault() {
+ return create((String) null);
+ }
+
+ /*
+ * Produces a {@link java.util.ResourceBundle} instance loading the properties file whose name
+ * is defined by the {@link Name} literal. If no value is specified
+ * then the default "messages.properties" file is loaded.
+ */
+ @Name
+ @Produces
+ public ResourceBundle create(InjectionPoint ip) {
+ String baseName = null;
+ if (ip != null && ip.getQualifiers() != null) {
+ Name nameQualifier = CDIUtils.getQualifier(Name.class, ip);
+ if (nameQualifier != null) {
+ baseName = nameQualifier.value();
+ if ("".equals(baseName)) {
+ baseName = null;
+ }
+ }
+ }
+
+ return create(baseName);
+ }
+
+ public static ResourceBundle create(String baseName) {
+ ResourceBundle bundle;
+
+ try {
+ bundle = baseName != null
+ ? new ResourceBundle(baseName, CDI.current().select(Locale.class).get()) {
+ }
+ : new ResourceBundle("messages", CDI.current().select(Locale.class).get());
+ } catch (RuntimeException e) {
+ bundle = baseName != null
+ ? new ResourceBundle(baseName, Locale.getDefault())
+ : new ResourceBundle("messages", Locale.getDefault());
+ }
+
+ return bundle;
+ }
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/util/CDIUtils.java b/core/src/main/java/org/demoiselle/jee/core/util/CDIUtils.java
new file mode 100644
index 0000000..83737ba
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/util/CDIUtils.java
@@ -0,0 +1,121 @@
+package org.demoiselle.util;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Utility class to peform useful operations on CDI discovered beans.
+ *
+ * @author SERPRO
+ */
+public final class CDIUtils {
+
+ private static final Annotation[] annotationArrayType = new Annotation[0];
+
+ /**
+ * Returns true
if one annotation of the provided type is present
+ * on a list of annotations.
+ *
+ * @param annotationType Annotation type being looked for.
+ * @param allAnnotations List of all annotations where to look for.
+ * @return true
if the annotation is present on the list
+ */
+ @SuppressWarnings("WeakerAccess")
+ public static boolean hasAnnotation(Class extends Annotation> annotationType, Annotation... allAnnotations) {
+ for (Annotation currentAnnotation : allAnnotations) {
+ if (currentAnnotation.annotationType().isAssignableFrom(annotationType)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param annotationType Type of the annotation being checked
+ * @param allAnnotations List of annotations to check for the specific one
+ * @see #hasAnnotation(Class, Annotation...)
+ * @return true
if the annotation is present on the list
+ */
+ @SuppressWarnings("WeakerAccess")
+ public static boolean hasAnnotation(Class extends Annotation> annotationType,
+ Collection allAnnotations) {
+ return hasAnnotation(annotationType, allAnnotations.toArray(annotationArrayType));
+ }
+
+ /**
+ * Returns true
if a base class is annotated with the provided annotation.
+ *
+ * @param annotationType Annotation type to look for
+ * @param baseType Class to check for the informed annotation
+ * @see #hasAnnotation(Class, Annotation...)
+ * @return true
if the annotation is present on the list
+ */
+ @SuppressWarnings("WeakerAccess")
+ public static boolean hasAnnotation(Class extends Annotation> annotationType, Class> baseType) {
+ return hasAnnotation(annotationType, baseType.getAnnotations());
+ }
+
+ /**
+ * Returns the annotation instance that matches the annotation type provided,
+ * or null
if no annotation of that type is present.
+ *
+ * @param annotationType Annotation type being looked for.
+ * @param allAnnotations List of all annotations where to look for.
+ * @param Type of the specific annotation returned
+ * @return The annotation instance found, or null
if there is no such annotation present.
+ */
+ @SuppressWarnings({ "WeakerAccess", "unchecked" })
+ public static T getAnnotation(Class annotationType, Annotation... allAnnotations) {
+ for (Annotation currentAnnotation : allAnnotations) {
+ if (currentAnnotation.annotationType().isAssignableFrom(annotationType)) {
+ return (T) currentAnnotation;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param annotationType Annotation type being looked for.
+ * @param allAnnotations List of all annotations where to look for.
+ * @param Type of the specific annotation returned
+ * @see #getAnnotation(Class, Annotation...)
+ * @return The annotation instance found, or null
if there is no such annotation present.
+ */
+ @SuppressWarnings({ "WeakerAccess" })
+ public static T getAnnotation(Class annotationType,
+ Collection allAnnotations) {
+ return getAnnotation(annotationType, allAnnotations.toArray(annotationArrayType));
+ }
+
+ /**
+ * Returns true
if one qualifier of the provided type is present
+ * on an injection point.
+ *
+ * @param qualifierAnnotationType Annotation type being looked for.
+ * @param ip Injection point of a bean type.
+ * @return true
if the annotation is present on the list
+ */
+ @SuppressWarnings("WeakerAccess")
+ public static boolean hasQualifier(Class extends Annotation> qualifierAnnotationType, InjectionPoint ip) {
+ return hasAnnotation(qualifierAnnotationType, ip.getQualifiers());
+ }
+
+ /**
+ * Returns the annotation instance that matches the annotation type provided,
+ * or null
if no annotation of that type is present.
+ *
+ * @param qualifierAnnotationType Annotation type being looked for.
+ * @param ip Injection point of a bean type.
+ * @param Type of the specific annotation returned
+ * @return The annotation instance found, or null
if there is no such annotation present.
+ */
+ @SuppressWarnings("WeakerAccess")
+ public static T getQualifier(Class qualifierAnnotationType, InjectionPoint ip) {
+ return getAnnotation(qualifierAnnotationType, ip.getQualifiers());
+ }
+
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/util/Exceptions.java b/core/src/main/java/org/demoiselle/jee/core/util/Exceptions.java
new file mode 100644
index 0000000..5a8d499
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/util/Exceptions.java
@@ -0,0 +1,67 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.util;
+
+/**
+ *Class that offer tow methods that can help with manipulation of throwable exceptions.
+ *
+ * @author SERPRO
+ */
+public final class Exceptions {
+
+ /**
+ * Constructor without parameters.
+ */
+ private Exceptions() {
+ }
+
+ /**
+ * Receives as parameter any kind of Throwable objects, and throws a RuntimeException instead.
+ *
+ * @param throwable
+ * a throwable object.
+ *
+ * @throws RuntimeException throws this kind of exception every time that is called.
+ */
+ public static void handleToRuntimeException(final Throwable throwable) throws RuntimeException {
+ if (throwable instanceof RuntimeException) {
+ throw (RuntimeException) throwable;
+ } else {
+ throw new RuntimeException(throwable);
+ }
+ }
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/util/Reflections.java b/core/src/main/java/org/demoiselle/jee/core/util/Reflections.java
new file mode 100644
index 0000000..3c73793
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/util/Reflections.java
@@ -0,0 +1,367 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.util;
+
+import java.io.InputStream;
+import java.lang.reflect.*;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Provides some features to do some operations relating to java reflection.
+ *
+ * @author SERPRO
+ */
+public class Reflections {
+
+ protected Reflections() {
+ // Impede instanciar subclasses desse tipo.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Return the parametized type used with a concrete implementation of a class that accepts generics. Ex: If you
+ * declare
+ *
+ * public class SpecializedCollection implements Collection<SpecializedType> {
+ * // ...
+ * }
+ *
+ * then the code getGenericTypeArgument(SpecializedCollection.class , 0);
will return the type
+ * SpecializedType
.
+ *
+ * @param type Base type to check for generic arguments
+ * @param idx zero based index of the generic argument to get
+ * @param Type of the generic argument
+ * @return The class representing the type of the generic argument
+ */
+ @SuppressWarnings("unchecked")
+ public static Class getGenericTypeArgument(final Type type, final int idx) {
+ ParameterizedType paramType;
+ try {
+ paramType = (ParameterizedType) type;
+ } catch (ClassCastException cause) {
+ return getGenericTypeArgument((Class) type, idx);
+ }
+
+ return (Class) paramType.getActualTypeArguments()[idx];
+ }
+
+ /**
+ * Return the parametized type used with a concrete implementation of a class that accepts generics. Ex: If you
+ * declare
+ *
+ *
+ * public class SpecializedCollection implements Collection<SpecializedType> {
+ * // ...
+ * }
+ *
+ *
+ * then the code getGenericTypeArgument(SpecializedCollection.class , 0);
will return the type
+ * SpecializedType
.
+ *
+ * @param clazz Base type to check for generic arguments
+ * @param idx zero based index of the generic argument to get
+ * @param Type of the generic argument
+ * @return The class representing the type of the generic argument
+ */
+ @SuppressWarnings("unchecked")
+ public static Class getGenericTypeArgument(final Class> clazz, final int idx) {
+ final Type type = clazz.getGenericSuperclass();
+
+ ParameterizedType paramType;
+ try {
+ paramType = (ParameterizedType) type;
+ } catch (ClassCastException cause) {
+ return getGenericTypeArgument((Class) type, idx);
+ }
+
+ return (Class) paramType.getActualTypeArguments()[idx];
+ }
+
+ /**
+ *
+ * Return the parametized type passed to field types that accepts Generics.
+ *
+ * Ex: If you declare
+ *
+ *
+ * public class MyClass{
+ * private Collection<String> myStringCollection;
+ * }
+ *
+ *
+ * then the code getGenericTypeArgument( MyClass.class.getDeclaredField("myStringCollection") , 0);
+ * will return the type String
.
+ *
+ * @param field Field which type is generified
+ * @param idx zero based index of the generic argument to get
+ * @param Type of the generic argument
+ * @return The class representing the type of the generic argument
+ */
+ @SuppressWarnings("unchecked")
+ public static Class getGenericTypeArgument(final Field field, final int idx) {
+ final Type type = field.getGenericType();
+ final ParameterizedType paramType = (ParameterizedType) type;
+
+ return (Class) paramType.getActualTypeArguments()[idx];
+ }
+
+ /**
+ *
+ * Return the parametized type passed to members (fields or methods) that accepts Generics.
+ *
+ *
+ * @param member Member which type is generified
+ * @param idx zero based index of the generic argument to get
+ * @param Type of the generic argument
+ * @return The class representing the type of the generic argument
+ * @see #getGenericTypeArgument(Field field, int idx)
+ */
+ public static Class getGenericTypeArgument(final Member member, final int idx) {
+ Class result = null;
+
+ if (member instanceof Field) {
+ result = getGenericTypeArgument((Field) member, idx);
+ } else if (member instanceof Method) {
+ result = getGenericTypeArgument((Method) member, idx);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * Return the parametized type passed to methods that accepts Generics.
+ *
+ *
+ * @param method Generified method reference
+ * @param idx zero based index of the generic argument to get
+ * @param Type of the generic argument
+ * @return The class representing the type of the generic argument
+ * @see #getGenericTypeArgument(Field field, int idx)
+ */
+ @SuppressWarnings("unchecked")
+ public static Class getGenericTypeArgument(final Method method, final int idx) {
+ return (Class) method.getGenericParameterTypes()[idx];
+ }
+
+ /**
+ * Returns the value contained in the given field.
+ *
+ * @param field field to be extracted the value.
+ * @param object object that contains the field.
+ * @param Type of the generic argument
+ * @return value of the field.
+ */
+ @SuppressWarnings("unchecked")
+ public static T getFieldValue(Field field, Object object) {
+ T result = null;
+
+ try {
+ boolean acessible = field.isAccessible();
+ field.setAccessible(true);
+ result = (T) field.get(object);
+ field.setAccessible(acessible);
+
+ } catch (Exception e) {
+ Exceptions.handleToRuntimeException(e);
+ }
+
+ return result;
+ }
+
+ /**
+ * Sets a value in a field.
+ *
+ * @param field field to be setted.
+ * @param object object that contains the field.
+ * @param value value to be setted in the field.
+ */
+ public static void setFieldValue(Field field, Object object, Object value) {
+ try {
+ boolean acessible = field.isAccessible();
+ field.setAccessible(true);
+ field.set(object, value);
+ field.setAccessible(acessible);
+
+ } catch (Exception e) {
+ Exceptions.handleToRuntimeException(e);
+ }
+ }
+
+ /**
+ * @param type Base type to look for fields
+ * @return All non static fields from a certain type. Inherited fields are not returned, so if you need to get
+ * inherited fields you must iterate over this type's hierarchy.
+ */
+ public static Field[] getNonStaticDeclaredFields(Class> type) {
+ List fields = new ArrayList();
+
+ if (type != null) {
+ for (Field field : type.getDeclaredFields()) {
+ if (!Modifier.isStatic(field.getModifiers()) && !field.getType().equals(type.getDeclaringClass())) {
+ fields.add(field);
+ }
+ }
+ }
+
+ return fields.toArray(new Field[0]);
+ }
+
+ /**
+ * @param type Base type to look for fields
+ * @return All non static fields from a certain type, including fields declared in superclasses of this type.
+ */
+ public static List getNonStaticFields(Class> type) {
+ List fields = new ArrayList();
+
+ if (type != null) {
+ Class> currentType = type;
+ while (currentType != null && !"java.lang.Object".equals(currentType.getCanonicalName())) {
+ fields.addAll(Arrays.asList(getNonStaticDeclaredFields(currentType)));
+ currentType = currentType.getSuperclass();
+ }
+ }
+
+ return fields;
+ }
+
+ /**
+ * Instantiate an object of the given type. The default constructor with no parameters is used.
+ *
+ * @param clazz Base type of object to instantiate
+ * @param Final type of instantiated object
+ * @return New instance of provided type
+ */
+ public static T instantiate(Class clazz) {
+ T object = null;
+ try {
+ object = clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ Exceptions.handleToRuntimeException(e);
+ }
+ return object;
+ }
+
+ /**
+ * Verifies if a given class could be converted to a given type.
+ *
+ * @param clazz class to be checked.
+ * @param type type to be checked.
+ * @return {@link Boolean} true if the given class can be converted to a given type, and false otherwise.
+ */
+ public static boolean isOfType(Class> clazz, Class> type) {
+ return type.isAssignableFrom(clazz) && clazz != type;
+ }
+
+ /**
+ * Obtains the {@link ClassLoader} for the given class, from his canonical name.
+ *
+ * @param canonicalName canonical name of the the given class.
+ * @return {@link ClassLoader} ClassLoader for the given class.
+ */
+ public static ClassLoader getClassLoaderForClass(final String canonicalName) {
+ return Reflections.getClassLoaderForResource(canonicalName.replaceAll("\\.", "/") + ".class");
+ }
+
+ /**
+ * Obtains the {@link ClassLoader} for the given resource.
+ *
+ * @param resource String representation of the fully qualified path to the resource on the classpath
+ * @return {@link ClassLoader} ClassLoader for the given resource.
+ */
+ public static ClassLoader getClassLoaderForResource(final String resource) {
+ final String stripped = resource.charAt(0) == '/' ? resource.substring(1) : resource;
+
+ URL url = null;
+ ClassLoader result = Thread.currentThread().getContextClassLoader();
+
+ if (result != null) {
+ url = result.getResource(stripped);
+ }
+
+ if (url == null) {
+ result = Reflections.class.getClassLoader();
+ url = Reflections.class.getClassLoader().getResource(stripped);
+ }
+
+ if (url == null) {
+ result = null;
+ }
+
+ return result;
+ }
+
+ /**
+ * Return an URL to access a resource available to the active classloader for the calling thread.
+ *
+ * @param resource String representation of the location of the resource on the classpath
+ * @return The {@link URL} for the resource
+ */
+ public static URL getResourceAsURL(final String resource) {
+ ClassLoader classLoader = getClassLoaderForResource(resource);
+ return classLoader != null ? classLoader.getResource(resource) : null;
+ }
+
+ /**
+ * Return an InputStream to access a resource available to the active classloader for the calling thread.
+ *
+ * @param resource String representation of the location of the resource on the classpath
+ * @return An {@link InputStream} that reads data from the resource
+ */
+ public static InputStream getResourceAsStream(final String resource) {
+ ClassLoader classLoader = getClassLoaderForResource(resource);
+ return classLoader != null ? classLoader.getResourceAsStream(resource) : null;
+ }
+
+ /**
+ * Loads a class with the given name using the active classloader for the current thread.
+ *
+ * @param className String with fully qualified class name of the desired class
+ * @param Final type of the loaded class
+ * @return Class representing the loaded type
+ * @throws ClassNotFoundException If no class with this name exists
+ */
+ @SuppressWarnings("unchecked")
+ public static Class forName(final String className) throws ClassNotFoundException {
+ ClassLoader classLoader = getClassLoaderForClass(className);
+ return (Class) Class.forName(className, true, classLoader);
+ }
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/util/ResourceBundle.java b/core/src/main/java/org/demoiselle/jee/core/util/ResourceBundle.java
new file mode 100644
index 0000000..be81746
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/util/ResourceBundle.java
@@ -0,0 +1,136 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.jee.core.util;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Set;
+
+/**
+ * The Demoiselle's ResourceBundle extends the abstraction {@link java.util.ResourceBundle},
+ * and provide the locale and the base name for the bundle.
+ *
+ * To select which resource properties file to load when injecting beans of this class, qualify
+ * the injection point with {@link org.demoiselle.annotation.Name}, using the resource name (without
+ * the '.properties' extension) as the value. If the injection point isn't qualified the default
+ * file messages.properties
will be loaded from the root of the classpath.
+ *
+ * @author SERPRO
+ */
+public class ResourceBundle extends java.util.ResourceBundle implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String baseName;
+
+ private transient java.util.ResourceBundle delegate;
+
+ private final Locale locale;
+
+ private java.util.ResourceBundle getDelegate() {
+ if (delegate == null) {
+ try {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ delegate = ResourceBundle.getBundle(baseName, locale, classLoader);
+
+ } catch (MissingResourceException mre) {
+ delegate = ResourceBundle.getBundle(baseName, locale);
+ }
+ }
+
+ return delegate;
+ }
+
+ /**
+ * Constructor that set values of baseName and locale.
+ *
+ * @param baseName
+ * the base name to construct the complete bundle name.
+ *
+ * @param locale
+ * locale to define the choosen bundle.
+ */
+ public ResourceBundle(String baseName, Locale locale) {
+ this.baseName = baseName;
+ this.locale = locale;
+ }
+
+ @Override
+ public boolean containsKey(String key) {
+ return getDelegate().containsKey(key);
+ }
+
+ @Override
+ public Enumeration getKeys() {
+ return getDelegate().getKeys();
+ }
+
+ @Override
+ public Locale getLocale() {
+ return getDelegate().getLocale();
+ }
+
+ @Override
+ public Set keySet() {
+ return getDelegate().keySet();
+ }
+
+ public String getString(String key, Object... params) {
+ return Strings.getString(getString(key), params);
+ }
+
+ @Override
+ protected Object handleGetObject(String key) {
+ Object result;
+
+ try {
+ Method method = getDelegate().getClass().getMethod("handleGetObject", String.class);
+
+ method.setAccessible(true);
+ result = method.invoke(delegate, key);
+ method.setAccessible(false);
+
+ } catch (Exception cause) {
+ throw new RuntimeException(cause);
+ }
+
+ return result;
+ }
+}
diff --git a/core/src/main/java/org/demoiselle/jee/core/util/Strings.java b/core/src/main/java/org/demoiselle/jee/core/util/Strings.java
new file mode 100644
index 0000000..b3e156e
--- /dev/null
+++ b/core/src/main/java/org/demoiselle/jee/core/util/Strings.java
@@ -0,0 +1,301 @@
+/*
+ * Demoiselle Framework
+ * Copyright (C) 2010 SERPRO
+ * ----------------------------------------------------------------------------
+ * This file is part of Demoiselle Framework.
+ *
+ * Demoiselle Framework is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License version 3
+ * along with this program; if not, see
+ * or write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301, USA.
+ * ----------------------------------------------------------------------------
+ * Este arquivo é parte do Framework Demoiselle.
+ *
+ * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
+ * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
+ * do Software Livre (FSF).
+ *
+ * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
+ * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
+ * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
+ * para maiores detalhes.
+ *
+ * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
+ * "LICENCA.txt", junto com esse programa. Se não, acesse
+ * ou escreva para a Fundação do Software Livre (FSF) Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+package org.demoiselle.jee.core.util;
+
+import org.demoiselle.jee.core.annotation.Ignore;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.demoiselle.util.Reflections;
+
+/**
+ * Contain a set of methods that implements a set of functionalities that
+ * envolves manipulation of strings.
+ *
+ * @author SERPRO
+ */
+public final class Strings {
+
+ private Strings() {
+ }
+
+ /**
+ * Returns if some string matches with the format of a ResourceBundle key or
+ * not.
+ *
+ * @param key string to check if matches with key format of ResourceBundle.
+ * @return boolean true if matches and false otherwise.
+ */
+ public static boolean isResourceBundleKeyFormat(final String key) {
+ return Pattern.matches("^\\{(.+)\\}$", key == null ? "" : key);
+ }
+
+ /**
+ * Removes specific characteres from a given string.
+ *
+ * @param string string to be changed, by the removing of some characters.
+ * @param chars characters to be removed from string.
+ * @return String returns the given string without the given characters.
+ */
+ public static String removeChars(String string, char... chars) {
+ String result = string;
+
+ if (result != null) {
+ for (char ch : chars) {
+ result = result.replace(String.valueOf(ch), "");
+ }
+ }
+ return result;
+ }
+
+ public static String join(String separator, String... strings) {
+ StringBuffer result = new StringBuffer();
+
+ if (strings != null) {
+ for (int i = 0; i < strings.length; i++) {
+ if (i != 0 && separator != null) {
+ result.append(separator);
+ }
+
+ if (strings[i] != null) {
+ result.append(strings[i]);
+ }
+ }
+ }
+
+ return result.length() > 0 ? result.toString() : null;
+ }
+
+ /**
+ * Inserts the character "0" in the begin of a given string. The quantity of
+ * zeros that will be placed depends on the difference between the length of
+ * the given string and the value of howMuchZeros.
+ *
+ * @param string string to insert zeros characthers.
+ * @param howMuchZeros its controls how much zeros will be insert.
+ * @return String Retuns the string, added with appropriate number of zeros.
+ * For exemplo, if string = "yes" and howMuchZeros = 5, the returned string
+ * will be "00yes".
+ */
+ public static String insertZeros(String string, int howMuchZeros) {
+ StringBuffer result = new StringBuffer((string == null ? "" : string).trim());
+ int difference = howMuchZeros - result.toString().length();
+
+ for (int j = 0; j < difference; j++) {
+ result.insert(0, '0');
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * * Replaces the numbers between braces in the given string with the given
+ * parameters. The process will replace a number between braces for the
+ * parameter for which its order in the set of parameters matches with the
+ * number of the given string. For exemple, if is received the following
+ * string "Treats an {0} exception" and the set of parameters
+ * {"DemoiselleException"}, the return will be the following string: "Treats
+ * an DemoiselleException exception".
+ *
+ * @param string with the numbers with braces to be replaced with the
+ * parameters.
+ * @param params parameters that will replace the number with braces in the
+ * given string.
+ * @return String string with numbers replaced with the matching parameter.
+ */
+ public static String getString(final String string, final Object... params) {
+ String result = null;
+
+ if (string != null) {
+ result = new String(string);
+ }
+
+ if (params != null && string != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (params[i] != null) {
+ result = result.replaceAll("\\{" + i + "\\}", Matcher.quoteReplacement(params[i].toString()));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Verifies if a given string is empty or null.
+ *
+ * @param string string to be verified.
+ * @return boolean returns true if the given string is empty or null and
+ * returns false otherwise.
+ */
+ public static boolean isEmpty(String string) {
+ return string == null || string.trim().isEmpty();
+ }
+
+ /**
+ * Converts any object to string.
+ *
+ * @param object object to be converted.
+ * @return String the given object converted to string.
+ */
+ public static String toString(Object object) {
+ StringBuffer result = new StringBuffer();
+ Object fieldValue;
+
+ if (object != null) {
+ result.append(object.getClass().getSimpleName());
+ result.append(" [");
+
+ boolean first = true;
+ for (Field field : Reflections.getNonStaticDeclaredFields(object.getClass())) {
+ if (!field.isAnnotationPresent(Ignore.class)) {
+ if (first) {
+ first = false;
+ } else {
+ result.append(", ");
+ }
+
+ result.append(field.getName());
+ result.append('=');
+ fieldValue = Reflections.getFieldValue(field, object);
+ result.append(fieldValue != null && fieldValue.getClass().isArray()
+ ? Arrays.toString((Object[]) fieldValue)
+ : fieldValue);
+ }
+ }
+
+ result.append(']');
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Replace the camel case string for a lowercase string separated for a
+ * given symbol.
+ *
+ * @param string string that separeted with camel case.
+ * @param symbol simbol to be the new separator for the given string.
+ * @return String the given string separated with the given symbol.
+ */
+ public static String camelCaseToSymbolSeparated(String string, String symbol) {
+ if (symbol == null) {
+ symbol = "";
+ }
+
+ return string == null ? null : string.replaceAll("\\B([A-Z])", symbol + "$1").toLowerCase();
+ }
+
+ /**
+ * Sets the first character of a given string to upper case.
+ *
+ * @param string Full string to convert
+ * @return String the given string with the first character setted to upper
+ * case.
+ */
+ public static String firstToUpper(String string) {
+ String result = string;
+
+ if (!Strings.isEmpty(string)) {
+ result = string.toUpperCase().charAt(0) + (string.length() > 1 ? string.substring(1) : "");
+ }
+
+ return result;
+ }
+
+ /**
+ * Removes braces from a given string.
+ *
+ * @param string Message to remove braces from
+ * @return String the given string without braces.
+ */
+ public static String removeBraces(String string) {
+ String result = string;
+
+ if (isResourceBundleKeyFormat(string)) {
+ result = string.substring(1, string.length() - 1);
+ }
+
+ return result;
+ }
+
+ /**
+ * Inserts braces in a given string.
+ *
+ * @param string Original string to insert braces on.
+ * @return String the given string with braces.
+ */
+ public static String insertBraces(String string) {
+ String result = string;
+
+ if (!isEmpty(string)) {
+ result = "{" + string + "}";
+ }
+
+ return result;
+ }
+
+ public static String parse(InputStream inputStream) throws IOException {
+ StringBuilder result = new StringBuilder();
+
+ if (inputStream != null) {
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new InputStreamReader(inputStream));
+ String line;
+
+ while ((line = reader.readLine()) != null) {
+ result.append(line);
+ }
+
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+
+ return result.length() > 0 ? result.toString() : null;
+ }
+}
--
libgit2 0.21.2