protected static URL getUrlForStringFromClasspathAsFileOrUrl(String logbackConfigurationFile) {

        URL url = null;

        try {
            url = Resources.getResource(logbackConfigurationFile);
        } catch (IllegalArgumentException ex) {
            // doing nothing intentionally..
        }

        if (url == null) {
            // configuring from file:
            try {
                File file = new File(logbackConfigurationFile);

                if (file.exists()) {
                    url = new File(logbackConfigurationFile).toURI().toURL();
                }

            } catch (MalformedURLException ex) {
                // doing nothing intentionally..
            }

        }

        if (url == null) {
            try {
                // we assume we got a real http://... url here...
                url = new URL(logbackConfigurationFile);
            } catch (MalformedURLException ex) {
                // doing nothing intentionally..
            }

        }

        return url;
    }

Looks up a potential file from
1) The classpahth
2) From the filesystem
3) From an URL

@param logbackConfigurationFile
@return null if not found or a valid url created from the logbackConfigurationFile

Looks up a potential file from 1 ) The classpahth 2 ) From the filesystem 3 ) From an URL


protected static String generateSecret(Random random) {

        String charsetForSecret = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        StringBuilder stringBuilder = new StringBuilder(64);

        for (int i = 0; i < 64; i++) {

            int charToPoPickFromCharset = random.nextInt(charsetForSecret.length());
            stringBuilder.append(charsetForSecret.charAt(charToPoPickFromCharset));

        }

        return stringBuilder.toString();

    }

!!!! Only for testing purposes !!!!

Usually you want to use {@link SecretGenerator#generateSecret()}

@param random the random generator to use. Usually new Random(), but for testing you can
use a predefined seed.
@return A String suitable as random secret for eg signing a session.


protected RunClassInSeparateJvmMachine buildRunClassInSeparateJvmMachine(
            String name,
            String classNameWithMainToRun,
            List<String> classpath,
            List<String> jvmArguments,
            File mavenBaseDir) {
        return new RunClassInSeparateJvmMachine(
            name,
            classNameWithMainToRun,
            classpath,
            buildJvmArguments(),
            mavenBaseDir
        );
    }

protected RunClassInSeparateJvmMachine buildRunClassInSeparateJvmMachine ( String name , String classNameWithMainToRun , List < String > classpath , List < String > jvmArguments , File mavenBaseDir ) { return new RunClassInSeparateJvmMachine ( name , classNameWithMainToRun , classpath , buildJvmArguments ( ) , mavenBaseDir ) ; }

so we can mock a fake one for unit testing


protected List<Artifact> getAllArtifactsComingFromNinjaStandalone(
        List<Artifact> artifacts) {

        List<Artifact> resultingArtifacts = new ArrayList<>();

        for (Artifact artifact: artifacts) {

            for (String dependencyTrail: artifact.getDependencyTrail()) {

                // something like:  org.ninjaframework:ninja-standalone:jar:2.5.2
                if (dependencyTrail.contains(NinjaMavenPluginConstants.NINJA_STANDALONE_ARTIFACT_ID)) {

                    resultingArtifacts.add(artifact);
                    break;

                }

            }

        }

        return resultingArtifacts;

    }

This might be a bit hacky. But just a little bit.

We have to add ninja-standalone and all of its dependencies to
the classpath, so that NinjaJetty can start.

But we do not want the user to declare the dependencies inside his
project pom.xml.

Therefore we declare the dependency in this plugin pom.xml.
But we do not want to include all of this plugin's dependencies in the
classpath for NinjaJetty. Therefore this method filters everything and
only adds  dependencies (also transitive deps) that originate
from ninja-standalone. That way we get all deps we need.

@param artifacts A list of artifacts that will be filtered.
@return All artifacts coming from artifactId "ninja-standalone"
(including transitive dependencies)

This might be a bit hacky . But just a little bit .


static public Class<? extends Standalone> resolveStandaloneClass() {
        return resolveStandaloneClass(
            System.getProperty(Standalone.KEY_NINJA_STANDALONE_CLASS),
            ForwardingServiceLoader.loadWithSystemServiceLoader(Standalone.class),
            Standalone.DEFAULT_STANDALONE_CLASS
        );
    }

static public Class < ? extends Standalone > resolveStandaloneClass ( ) { return resolveStandaloneClass ( System . getProperty ( Standalone . KEY_NINJA_STANDALONE_CLASS ) , ForwardingServiceLoader . loadWithSystemServiceLoader ( Standalone . class ) , Standalone . DEFAULT_STANDALONE_CLASS ) ; }

Resolves which standalone class to use. Either defined as a system
property or falling back to the default.
@return The resolved standalone class to use

Resolves which standalone class to use . Either defined as a system property or falling back to the default .


public String encrypt(String data) {

        Objects.requireNonNull(data, "Data to be encrypted");

        if (!secretKeySpec.isPresent()) {
            return data;
        }

        try {
            // encrypt data
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec.get());
            byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));

            // convert encrypted bytes to string in base64
            return Base64.encodeBase64URLSafeString(encrypted);

        } catch (InvalidKeyException ex) {
            logger.error(getHelperLogMessage(), ex);
            throw new RuntimeException(ex);
        } catch (GeneralSecurityException ex) {
            logger.error("Failed to encrypt data.", ex);
            return "";
        }
    }

Encrypts data with secret key.

@param data text to encrypt
@return encrypted text in base64 format


public String decrypt(String data) {

        Objects.requireNonNull(data, "Data to be decrypted");

        if (!secretKeySpec.isPresent()) {
            return data;
        }

        // convert base64 encoded string to bytes
        byte[] decoded = Base64.decodeBase64(data);
        try {
            // decrypt bytes
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec.get());
            byte[] decrypted = cipher.doFinal(decoded);

            // convert bytes to string
            return new String(decrypted, StandardCharsets.UTF_8);

        } catch (InvalidKeyException ex) {
            logger.error(getHelperLogMessage(), ex);
            throw new RuntimeException(ex);
        } catch (GeneralSecurityException ex) {
            logger.error("Failed to decrypt data.", ex);
            return "";
        }
    }

Decrypts data with secret key.

@param data text to decrypt in base64 format
@return decrypted text


private final String readNinjaVersion() {

        // location of the properties file
        String LOCATION_OF_NINJA_BUILTIN_PROPERTIES = "ninja/ninja-builtin.properties";
        // and the key inside the properties file.
        String NINJA_VERSION_PROPERTY_KEY = "ninja.version";

        String ninjaVersion;
        try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(LOCATION_OF_NINJA_BUILTIN_PROPERTIES)){

            Properties prop = new Properties();
            prop.load(stream);

            ninjaVersion = prop.getProperty(NINJA_VERSION_PROPERTY_KEY);

        } catch (Exception e) {
            //this should not happen. Never.
            throw new RuntimeErrorException(new Error("Something is wrong with your build. Cannot find resource " + LOCATION_OF_NINJA_BUILTIN_PROPERTIES));
        }

        return ninjaVersion;

    }

Simply reads a property resource file that contains the version of this
Ninja build. Helps to identify the Ninja version currently running.

@return The version of Ninja. Eg. "1.6-SNAPSHOT" while developing of "1.6" when released.

Simply reads a property resource file that contains the version of this Ninja build . Helps to identify the Ninja version currently running .


private void register(Path path) throws IOException {
        ////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        //// USUALLY THIS IS THE DEFAULT WAY TO REGISTER THE EVENTS:
        ////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        //        WatchKey watchKey = path.register(
        //                watchService,
        //                ENTRY_CREATE,
        //                ENTRY_DELETE,
        //                ENTRY_MODIFY);

        ////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        //// BUT THIS IS DAMN SLOW (at least on a Mac)
        //// THEREFORE WE USE EVENTS FROM COM.SUN PACKAGES THAT ARE WAY FASTER
        //// THIS MIGHT BREAK COMPATIBILITY WITH OTHER JDKs
        //// MORE: http://stackoverflow.com/questions/9588737/is-java-7-watchservice-slow-for-anyone-else
        ////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        WatchKey watchKey = path.register(
            watchService,
            new WatchEvent.Kind[]{
                StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_MODIFY,
                StandardWatchEventKinds.ENTRY_DELETE
            },
            SensitivityWatchEventModifier.HIGH);

        mapOfWatchKeysToPaths.put(watchKey, path);
    }

//        WatchKey watchKey = path.register(

Register the given path with the WatchService


public static NinjaMode determineModeFromSystemPropertiesOrProdIfNotSet() {

        Optional<NinjaMode> ninjaModeOptional = determineModeFromSystemProperties();
        NinjaMode ninjaMode;

        if (!ninjaModeOptional.isPresent()) {
            ninjaMode = NinjaMode.prod;
        } else {
            ninjaMode = ninjaModeOptional.get();
        }

        logger.info("Ninja is running in mode {}", ninjaMode.toString());

        return ninjaMode;

    }

returns NinjaMode.dev if no mode is set. Or the valid mode
set via a System Property called "ninja.mode".

E.g. under mvn you can use mvn ... -Dninja.mode=prod or so. Valid values
for ninja.mode are "prod", "dev", "test".

@return The valid mode set via a System Property called "ninja.mode"
or NinjaMode.dev if it is not set.

returns NinjaMode . dev if no mode is set . Or the valid mode set via a System Property called ninja . mode .


public boolean isValidMimeType(String mimeType) {
        if (mimeType == null) {
            return false;
        } else if (mimeType.indexOf(";") != -1) {
            return mimetypes.contains(mimeType.split(";")[0]);
        } else {
            return mimetypes.contains(mimeType);
        }
    }

public boolean isValidMimeType ( String mimeType ) { if ( mimeType == null ) { return false ; } else if ( mimeType . indexOf ( ";" ) != - 1 ) { return mimetypes . contains ( mimeType . split ( ";" ) [ 0 ] ) ; } else { return mimetypes . contains ( mimeType ) ; } }

check the mimetype is referenced in the mimetypes database

@param mimeType
the mimeType to verify


public Route buildRoute(Injector injector) {
        if (functionalMethod == null) {
            log.error("Error in route configuration for {}", uri);
            throw new IllegalStateException("Route missing a controller method");
        }

        // Calculate filters
        LinkedList<Class<? extends Filter>> allFilters = new LinkedList<>();

        allFilters.addAll(calculateGlobalFilters(this.globalFiltersOptional, injector));

        allFilters.addAll(this.localFilters);

        allFilters.addAll(calculateFiltersForClass(functionalMethod.getDeclaringClass()));
        FilterWith filterWith = functionalMethod.getAnnotation(FilterWith.class);
        if (filterWith != null) {
            allFilters.addAll(Arrays.asList(filterWith.value()));
        }

        FilterChain filterChain = buildFilterChain(injector, allFilters);

        return new Route(httpMethod, uri, functionalMethod, filterChain);
    }

public
Route
buildRoute
(
Injector
injector
)
{
if
(
functionalMethod
==
)
{
log
.
error
(
"Error in route configuration for {}"
,
uri
)
;
throw
new
IllegalStateException
(
"Route missing a controller method"
)
;
}
// Calculate filters
LinkedList
<
Class
<
extends
Filter
>
>
allFilters
=
new
LinkedList
<>
(
)
;
allFilters
.
addAll
(
calculateGlobalFilters
(
this
.
globalFiltersOptional
,
injector
)
)
;
allFilters
.
addAll
(
this
.
localFilters
)
;
allFilters
.
addAll
(
calculateFiltersForClass
(
functionalMethod
.
getDeclaringClass
(
)
)
)
;
FilterWith
filterWith
=
functionalMethod
.
getAnnotation
(
FilterWith
.
class
)
;
if
(
filterWith
!=
)
{
allFilters
.
addAll
(
Arrays
.
asList
(
filterWith
.
value
(
)
)
)
;
}
FilterChain
filterChain
=
buildFilterChain
(
injector
,
allFilters
)
;
return
new
Route
(
httpMethod
,
uri
,
functionalMethod
,
filterChain
)
;
}

Build the route.
@param injector The injector to build the route with
@return The built route


@Override
    final public void run() {
        // name current thread for improved logging/debugging
        Thread.currentThread().setName(this.name);

        try {
            this.configure();
        } catch (Exception e) {
            logger.error("Unable to configure {}", name, e);
            System.exit(1);
        }

        try {
            this.start();
        } catch (Exception e) {
            logger.error("Unable to start {}", name, e);
            System.exit(1);
        }

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                shutdown();
            }
        });

        try {
            // do not simply exit main() -- join something (likely server)
            join();
        } catch (Exception e) {
            logger.warn("Interrupted (most likely JVM is shutting down and this is safe to ignore)");
        }
    }

Configure, start, add shutdown hook, and join.  Does not exit.

Configure start add shutdown hook and join . Does not exit .


protected String createServerUrl(String scheme, String host, Integer port) {
        StringBuilder sb = new StringBuilder();

        sb.append(scheme);
        sb.append("://");
        sb.append((host != null ? host : "localhost"));

        if (("http".equals(scheme) && port != 80) || ("https".equals(scheme) && port != 443)) {
            sb.append(":");
            sb.append(port);
        }

        return sb.toString();
    }

protected String createServerUrl ( String scheme , String host , Integer port ) { StringBuilder sb = new StringBuilder ( ) ; sb . append ( scheme ) ; sb . append ( "://" ) ; sb . append ( ( host != null ? host : "localhost" ) ) ; if ( ( "http" . equals ( scheme ) && port != 80 ) || ( "https" . equals ( scheme ) && port != 443 ) ) { sb . append ( ":" ) ; sb . append ( port ) ; } return sb . toString ( ) ; }


@Override
    public void init(Router router) {
        this.router = router;
        configureReflections();

        controllers = Maps.newHashMap();
        methods = Sets.newHashSet();

        processFoundMethods();
        sortMethods();
        registerMethods();
    }

@ Override public void init ( Router router ) { this . router = router ; configureReflections ( ) ; controllers = Maps . newHashMap ( ) ; methods = Sets . newHashSet ( ) ; processFoundMethods ( ) ; sortMethods ( ) ; registerMethods ( ) ; }

Scans, identifies, and registers annotated controller methods for the
current runtime settings.

@param router

Scans identifies and registers annotated controller methods for the current runtime settings .


private void processFoundMethods() {
        for (Method method : findControllerMethods()) {
            if (allowMethod(method)) {

                // add the method to our todo list
                methods.add(method);

                // generate the paths for the controller class
                final Class<?> controllerClass = method.getDeclaringClass();

                if (!controllers.containsKey(controllerClass)) {

                    Set<String> paths = collectPaths(controllerClass);
                    controllers.put(controllerClass, paths);

                }
            }
        }
    }

Takes the found methods and checks if they have a valid format.
If they do, the controller path classes for these methods are generated

Takes the found methods and checks if they have a valid format . If they do the controller path classes for these methods are generated


private void sortMethods() {
        List<Method> methodList = new ArrayList<>(methods);
        Collections.sort(methodList, new Comparator<Method>() {

            @Override
            public int compare(Method m1, Method m2) {
                int o1 = Integer.MAX_VALUE;
                if (m1.isAnnotationPresent(Order.class)) {
                    Order order = m1.getAnnotation(Order.class);
                    o1 = order.value();
                }

                int o2 = Integer.MAX_VALUE;
                if (m2.isAnnotationPresent(Order.class)) {
                    Order order = m2.getAnnotation(Order.class);
                    o2 = order.value();
                }

                if (o1 == o2) {
                    // same or unsorted, compare controller+method
                    String s1 = m1.getDeclaringClass().getName() + "."
                            + m1.getName();
                    String s2 = m2.getDeclaringClass().getName() + "."
                            + m2.getName();
                    return s1.compareTo(s2);
                }

                if (o1 < o2) {
                    return -1;
                } else {
                    return 1;
                }
            }
        });
        methods = new LinkedHashSet<>(methodList);
    }

Sorts the methods into registration order


@SuppressWarnings("unchecked")
    private Set<Method> findControllerMethods() {
        Set<Method> methods = Sets.newLinkedHashSet();

        methods.addAll(reflections.getMethodsAnnotatedWith(Path.class));

        boolean enableCustomHttpMethods = ninjaProperties.getBooleanWithDefault(NINJA_CUSTOM_HTTP_METHODS, false);

        if (enableCustomHttpMethods) {

            Reflections annotationReflections = new Reflections("", new TypeAnnotationsScanner(), new SubTypesScanner());
            for (Class<?> httpMethod : annotationReflections.getTypesAnnotatedWith(HttpMethod.class)) {
                if (httpMethod.isAnnotation()) {
                    methods.addAll(reflections.getMethodsAnnotatedWith((Class<? extends Annotation>) httpMethod));
                }
            }

        } else {

            // Only look for standard HTTP methods annotations
            Reflections annotationReflections = new Reflections("ninja.jaxy", new TypeAnnotationsScanner(), new SubTypesScanner());
            for (Class<?> httpMethod : annotationReflections.getTypesAnnotatedWith(HttpMethod.class)) {
                if (httpMethod.isAnnotation()) {
                    methods.addAll(reflections.getMethodsAnnotatedWith((Class<? extends Annotation>) httpMethod));
                }
            }

        }

        return methods;
    }

Searches for Methods that have either a Path Annotation or a HTTP-Method Annotation

Searches for Methods that have either a Path Annotation or a HTTP - Method Annotation


private void configureReflections() {
        Optional<String> basePackage = Optional.ofNullable(ninjaProperties.get(NinjaConstant.APPLICATION_MODULES_BASE_PACKAGE));

        if (basePackage.isPresent()) {
            reflections = new Reflections(
                    basePackage.get() + "." + NinjaConstant.CONTROLLERS_DIR,
                    new MethodAnnotationsScanner());
        } else {
            reflections = new Reflections(
                    NinjaConstant.CONTROLLERS_DIR,
                    new MethodAnnotationsScanner());
        }
    }

private void configureReflections ( ) { Optional < String > basePackage = Optional . ofNullable ( ninjaProperties . get ( NinjaConstant . APPLICATION_MODULES_BASE_PACKAGE ) ) ; if ( basePackage . isPresent ( ) ) { reflections = new Reflections ( basePackage . get ( ) + "." + NinjaConstant . CONTROLLERS_DIR , new MethodAnnotationsScanner ( ) ) ; } else { reflections = new Reflections ( NinjaConstant . CONTROLLERS_DIR , new MethodAnnotationsScanner ( ) ) ; } }

Configures the set of packages to scan for annotated controller methods.

Configures the set of packages to scan for annotated controller methods .


private boolean allowMethod(Method method) {

        // NinjaProperties-based route exclusions/inclusions
        if (method.isAnnotationPresent(Requires.class)) {
            String key = method.getAnnotation(Requires.class).value();
            String value = ninjaProperties.get(key);
            if (value == null) {
                return false;
            }
        }

        // NinjaMode-based route exclusions/inclusions
        Set<NinjaMode> modes = Sets.newTreeSet();
        for (Annotation annotation : method.getAnnotations()) {

            Class<? extends Annotation> annotationClass = annotation
                    .annotationType();

            if (annotationClass.isAnnotationPresent(RuntimeMode.class)) {

                RuntimeMode mode = annotationClass
                        .getAnnotation(RuntimeMode.class);
                modes.add(mode.value());

            }
        }

        return modes.isEmpty() || modes.contains(runtimeMode);
    }

Determines if this method may be registered as a route. Ninja properties
are considered as well as runtime modes.

@param method
@return true if the method can be registered as a route

Determines if this method may be registered as a route . Ninja properties are considered as well as runtime modes .


private String getHttpMethod(Method method) {

        for (Annotation annotation : method.getAnnotations()) {

            Class<? extends Annotation> annotationClass = annotation
                    .annotationType();

            if (annotationClass.isAnnotationPresent(HttpMethod.class)) {
                HttpMethod httpMethod = annotationClass
                        .getAnnotation(HttpMethod.class);
                return httpMethod.value();
            }

        }

        // default to GET
        logger.info(String
                .format("%s.%s does not specify an HTTP method annotation! Defaulting to GET.",
                        method.getClass().getName(), method.getName()));

        return HttpMethod.GET;
    }

Returns the HTTP method for the controller method. Defaults to GET if
unspecified.

@param method
@return the http method for this controller method

Returns the HTTP method for the controller method . Defaults to GET if unspecified .


public static ControllerMethodInvoker build(
            Method functionalMethod,
            Method implementationMethod,
            Injector injector,
            NinjaProperties ninjaProperties) {
        // get both the parameters...
        final Type[] genericParameterTypes = implementationMethod.getGenericParameterTypes();
        final MethodParameter[] methodParameters = MethodParameter.convertIntoMethodParameters(genericParameterTypes);
        // ... and all annotations for the parameters
        final Annotation[][] paramAnnotations = implementationMethod
                .getParameterAnnotations();

        ArgumentExtractor<?>[] argumentExtractors = new ArgumentExtractor<?>[methodParameters.length];

        // now we skip through the parameters and process the annotations
        for (int i = 0; i < methodParameters.length; i++) {
            try {
                argumentExtractors[i] = getArgumentExtractor(methodParameters[i], paramAnnotations[i],
                        injector);
            } catch (RoutingException e) {
                throw new RoutingException("Error building argument extractor for parameter " + i +
                        " in method " + implementationMethod.getDeclaringClass().getName() + "." + implementationMethod.getName() + "()", e);
            }
        }

        // Replace a null extractor with a bodyAs extractor, but make sure there's only one
        int bodyAsFound = -1;
        for (int i = 0; i < argumentExtractors.length; i++) {
            if (argumentExtractors[i] == null) {
                if (bodyAsFound > -1) {
                    throw new RoutingException("Only one parameter may be deserialised as the body "
                            + implementationMethod.getDeclaringClass().getName() + "." + implementationMethod.getName() + "()\n"
                            + "Extracted parameter is type: " + methodParameters[bodyAsFound].parameterClass.getName() + "\n"
                            + "Extra parmeter is type: " + methodParameters[i].parameterClass.getName());
                } else {
                    argumentExtractors[i] = new ArgumentExtractors.BodyAsExtractor(methodParameters[i].parameterClass);
                    bodyAsFound = i;
                }
            }
        }

        // Now that every parameter has an argument extractor we can run validation on the annotated
        // parameters
        for (int i = 0; i < argumentExtractors.length; i++) {
            argumentExtractors[i] =
                    validateArgumentWithExtractor(
                            methodParameters[i],
                            paramAnnotations[i],
                            injector,
                            argumentExtractors[i]);
        }

        boolean useStrictArgumentExtractors = determineWhetherToUseStrictArgumentExtractorMode(ninjaProperties);

        return new ControllerMethodInvoker(functionalMethod, argumentExtractors, useStrictArgumentExtractors);
    }

Builds an invoker for a functional method.  Understands what parameters
to inject and extract based on type and annotations.
@param functionalMethod The method to be invoked
@param implementationMethod The method to use for determining what
actual parameters and annotations to use for each argument.  Useful
when type/lambda erasure makes the functional interface not reliable
for reflecting.
@param injector The guice injector
@param ninjaProperties The NinjaProperties of this application
@return An invoker

Builds an invoker for a functional method . Understands what parameters to inject and extract based on type and annotations .


public static String getRealClassNameLowerCamelCase(Object object) {

        return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, object.getClass().getSimpleName());

    }

public static String getRealClassNameLowerCamelCase ( Object object ) { return CaseFormat . UPPER_CAMEL . to ( CaseFormat . LOWER_CAMEL , object . getClass ( ) . getSimpleName ( ) ) ; }

Returns the lower class name. Eg. A class named MyObject will become
"myObject".

@param object Object for which to return the lowerCamelCaseName
@return the lowerCamelCaseName of the Object

Returns the lower class name . Eg . A class named MyObject will become myObject .


public static boolean doesClassExist(String nameWithPackage, Object instanceToGetClassloaderFrom) {
        boolean exists = false;

        try {
            Class.forName(nameWithPackage, false, instanceToGetClassloaderFrom.getClass().getClassLoader());
            exists = true;
        } catch (ClassNotFoundException e) {
            exists = false;
        }

        return exists;
    }

public static boolean doesClassExist ( String nameWithPackage , Object instanceToGetClassloaderFrom ) { boolean exists = false ; try { Class . forName ( nameWithPackage , false , instanceToGetClassloaderFrom . getClass ( ) . getClassLoader ( ) ) ; exists = true ; } catch ( ClassNotFoundException e ) { exists = false ; } return exists ; }

Used to check whether a class exists on the classpath.

@param nameWithPackage  for instance com.example.conf.GloablFilters
@param instanceToGetClassloaderFrom usually "this" if you call this method.
@return true if class exists, false if not.

Used to check whether a class exists on the classpath .


static public String getSourceCodeRelativePathForStackTraceElement(StackTraceElement ste) {
        String packageName = ste.getClassName();
        // e.g. com.fizzed.test.Application$1 for an internal class
        int pos = packageName.lastIndexOf('.');
        if (pos > 0) {
            packageName = packageName.substring(0, pos);
            return
                packageName.replace(".", File.separator)
                + File.separator
                + ste.getFileName();
        } else {
            // must be in default package
            return
                ste.getFileName();
        }
    }

Calculates the relative path of the source code file of a StackTrace
element if its available. Uses the packageName of the class to create a relative path
and appends the "filename" included with the stack trace element.
@param ste The stack trace element
@return The relative path of the source code file or null if the information
wasn't available in the stack trace element.

Calculates the relative path of the source code file of a StackTrace element if its available . Uses the packageName of the class to create a relative path and appends the filename included with the stack trace element .


public void add(String key, Object value, String expiration) {
        checkSerializable(value);
        cache.add(key, value, TimeUtil.parseDuration(expiration));
    }

public void add ( String key , Object value , String expiration ) { checkSerializable ( value ) ; cache . add ( key , value , TimeUtil . parseDuration ( expiration ) ) ; }

Add an element only if it doesn't exist.
@param key Element key
@param value Element value
@param expiration Ex: 10s, 3mn, 8h

Add an element only if it doesn t exist .


@SuppressWarnings("unchecked")
    public <T> T get(String key, Class<T> clazz) {
        return (T) cache.get(key);
    }

@ SuppressWarnings ( "unchecked" ) public < T > T get ( String key , Class < T > clazz ) { return ( T ) cache . get ( key ) ; }

Convenient clazz to get a value a class type;
@param <T> The needed type
@param key The element key
@param clazz The type class
@return The element value or null

Convenient clazz to get a value a class type ;


void checkSerializable(Object value) {
        if (value != null && !(value instanceof Serializable)) {
            throw new CacheException(
                    "Cannot cache a non-serializable value of type "
                            + value.getClass().getName(),
                    new NotSerializableException(value.getClass().getName()));
        }
    }

Utility that check that an object is serializable.

Utility that check that an object is serializable .


public Result render(String key, Object value) {

        render(new AbstractMap.SimpleEntry<String, Object>(key, value));

        return this;

    }

public Result render ( String key , Object value ) { render ( new AbstractMap . SimpleEntry < String , Object > ( key , value ) ) ; return this ; }

Implicitly generates a hashmap as object being rendered and adds
this key, value pair. If the object being rendered is already a hashmap
it simply adds this key value pair to it.

@param key The key to use.
@param value The value to use.
@return The Result for chaining.

Implicitly generates a hashmap as object being rendered and adds this key value pair . If the object being rendered is already a hashmap it simply adds this key value pair to it .


@Deprecated
    public Result renderRaw(final String string) {

        Renderable renderable = new Renderable() {

            @Override
            public void render(Context context, Result result) {

                if (result.getContentType() == null) {
                    result.contentType(Result.TEXT_PLAIN);
                }

                ResponseStreams resultJsonCustom = context
                        .finalizeHeaders(result);

                try (Writer writer = resultJsonCustom.getWriter()) {

                    writer.write(string);

                } catch (IOException ioException) {

                    logger.error(
                            "Error rendering raw String via renderRaw(...)",
                            ioException);
                }

            }
        };

        render(renderable);

        return this;

    }

This method directly renders the String to the output. It completely
bypasses any rendering engine.

Thus you can render anything you want.

Chaining of resultRaw().resultRaw()... is NOT supported. Mixing with
render() is NOT supported.

It is always recommended to implement your own RenderingEngine OR use
existing rendering engines.

Example: <code>
public Result controllerMethod() {
String customJson = "{\"user\" : \"john@woo.com\"}";

return Results.json().renderRaw(customJson);
}
</code>

@param string
The string to render.
@return A result that will render the string directly to the output
stream.
@deprecated => use text().render(string), html().render(string),
json().render(string), xml().render(string), or
contentType(type).render(string).

This method directly renders the String to the output . It completely bypasses any rendering engine .


public Result renderRaw(final byte [] bytes) {

        Renderable renderable = new Renderable() {

            @Override
            public void render(Context context, Result result) {
                if (result.getContentType() == null) {
                    result.contentType(Result.APPLICATION_OCTET_STREAM);
                }
                ResponseStreams responseStreams = context
                        .finalizeHeaders(result);

                try (OutputStream outputStream = responseStreams.getOutputStream()) {

                    outputStream.write(bytes);

                } catch (IOException ioException) {
                    throw new InternalServerErrorException(ioException);
                }
            }
        };

        render(renderable);

        return this;

   }

public Result renderRaw ( final byte [ ] bytes ) { Renderable renderable = new Renderable ( ) { @ Override public void render ( Context context , Result result ) { if ( result . getContentType ( ) == null ) { result . contentType ( Result . APPLICATION_OCTET_STREAM ) ; } ResponseStreams responseStreams = context . finalizeHeaders ( result ) ; try ( OutputStream outputStream = responseStreams . getOutputStream ( ) ) { outputStream . write ( bytes ) ; } catch ( IOException ioException ) { throw new InternalServerErrorException ( ioException ) ; } } } ; render ( renderable ) ; return this ; }

This method directly renders the byte array to the output. It
completely bypasses any rendering engine.

Thus you can render anything you want.

Chaining of resultRaw().resultRaw()... is NOT supported. Mixing with render()
is NOT supported.

It is always recommended to implement your own RenderingEngine OR
use existing rendering engines.

@param bytes The bytes to render.
@return A result that will render the string directly to the output stream.

This method directly renders the byte array to the output . It completely bypasses any rendering engine .


public Cookie getCookie(String cookieName) {

        for (Cookie cookie : getCookies()) {
            if (cookie.getName().equals(cookieName)) {
                return cookie;
            }
        }

        return null;
    }

public Cookie getCookie ( String cookieName ) { for ( Cookie cookie : getCookies ( ) ) { if ( cookie . getName ( ) . equals ( cookieName ) ) { return cookie ; } } return null ; }

Returns cookie with that name or null.

@param cookieName Name of the cookie
@return The cookie or null if not found.


public Result doNotCacheContent() {

        addHeader(CACHE_CONTROL, CACHE_CONTROL_DEFAULT_NOCACHE_VALUE);
        addHeader(DATE, DateUtil.formatForHttpHeader(System.currentTimeMillis()));
        addHeader(EXPIRES, DateUtil.formatForHttpHeader(0L));

        return this;

    }

public Result doNotCacheContent ( ) { addHeader ( CACHE_CONTROL , CACHE_CONTROL_DEFAULT_NOCACHE_VALUE ) ; addHeader ( DATE , DateUtil . formatForHttpHeader ( System . currentTimeMillis ( ) ) ) ; addHeader ( EXPIRES , DateUtil . formatForHttpHeader ( 0L ) ) ; return this ; }

This function sets

Cache-Control: no-cache, no-store
Date: (current date)
Expires: 1970

=> it therefore effectively forces the browser and every proxy in between
not to cache content.

See also https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers

@return this result for chaining.


public static void checkThatApplicationSecretIsSet(
                                                boolean isProd,
                                                String baseDirWithoutTrailingSlash,
                                                PropertiesConfiguration defaultConfiguration,
                                                Configuration compositeConfiguration) {

        String applicationSecret = compositeConfiguration.getString(NinjaConstant.applicationSecret);

        if (applicationSecret == null
                || applicationSecret.isEmpty()) {

            // If in production we stop the startup process. It simply does not make
            // sense to run in production if the secret is not set.
            if (isProd) {
                String errorMessage = "Fatal error. Key application.secret not set. Please fix that.";
                logger.error(errorMessage);
                throw new RuntimeException(errorMessage);
            }

            logger.info("Key application.secret not set. Generating new one and setting in conf/application.conf.");

            // generate new secret
            String secret = SecretGenerator.generateSecret();

            // set in overall composite configuration => this enables this instance to
            // start immediately. Otherwise we would have another build cycle.
            compositeConfiguration.setProperty(NinjaConstant.applicationSecret, secret);

            // defaultConfiguration is: conf/application.conf (not prefixed)
            defaultConfiguration.setProperty(NinjaConstant.applicationSecret, secret);

            try {

                // STEP 1: Save in source directories:
                // save to compiled version => in src/main/target/
                String pathToApplicationConfInSrcDir = baseDirWithoutTrailingSlash + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator + NinjaProperties.CONF_FILE_LOCATION_BY_CONVENTION;
                Files.createParentDirs(new File(pathToApplicationConfInSrcDir));
                // save to source
                defaultConfiguration.save(pathToApplicationConfInSrcDir);

                // STEP 2: Save in classes dir (target/classes or similar).
                // save in target directory (compiled version aka war aka classes dir)
                defaultConfiguration.save();

            } catch (ConfigurationException e) {
                logger.error("Error while saving new secret to application.conf.", e);
            } catch (IOException e) {
                logger.error("Error while saving new secret to application.conf.", e);
            }

        }

    }

This method checks that your configurations have set a
application.secret=23r213r12r123

If application.secret is missing or is empty it will do the following:
- In dev and test mode it'll generate a new application secret and write the secret
to both src/main/java/conf/application.conf and the classes dir were the compiled stuff
goes.
- In prod it will throw a runtime exception and stop the server.

This method checks that your configurations have set a application . secret = 23r213r12r123


public boolean addAll(@NonNull final Collection<? extends T> collection) {
        boolean result = mItems.addAll(collection);
        notifyDataSetChanged();
        return result;
    }

public boolean addAll ( @ NonNull final Collection < ? extends T > collection ) { boolean result = mItems . addAll ( collection ) ; notifyDataSetChanged ( ) ; return result ; }

Adds the objects in the specified collection to the end of this List. The objects are added in the order in which they are returned from the collection's iterator.

@param collection the collection of objects.

@return {@code true} if this {@code List} is modified, {@code false} otherwise.

Adds the objects in the specified collection to the end of this List . The objects are added in the order in which they are returned from the collection s iterator .


private int getPositionForId(final long itemId) {
        View v = getViewForId(itemId);
        if (v == null) {
            return AdapterView.INVALID_POSITION;
        } else {
            return mWrapper.getPositionForView(v);
        }
    }

private int getPositionForId ( final long itemId ) { View v = getViewForId ( itemId ) ; if ( v == null ) { return AdapterView . INVALID_POSITION ; } else { return mWrapper . getPositionForView ( v ) ; } }

Retrieves the position in the list corresponding to itemId.

@return the position of the item in the list, or {@link android.widget.AdapterView#INVALID_POSITION} if the {@code View} corresponding to the id was not found.

Retrieves the position in the list corresponding to itemId .


private void switchViews(final View switchView, final long switchId, final float translationY) {
        assert mHoverDrawable != null;
        assert mAdapter != null;
        assert mMobileView != null;

        final int switchViewPosition = mWrapper.getPositionForView(switchView);
        int mobileViewPosition = mWrapper.getPositionForView(mMobileView);

        ((Swappable) mAdapter).swapItems(switchViewPosition - mWrapper.getHeaderViewsCount(), mobileViewPosition - mWrapper.getHeaderViewsCount());
        ((BaseAdapter) mAdapter).notifyDataSetChanged();

        mHoverDrawable.shift(switchView.getHeight());
        mSwitchViewAnimator.animateSwitchView(switchId, translationY);
    }

private void switchViews ( final View switchView , final long switchId , final float translationY ) { assert mHoverDrawable != null ; assert mAdapter != null ; assert mMobileView != null ; final int switchViewPosition = mWrapper . getPositionForView ( switchView ) ; int mobileViewPosition = mWrapper . getPositionForView ( mMobileView ) ; ( ( Swappable ) mAdapter ) . swapItems ( switchViewPosition - mWrapper . getHeaderViewsCount ( ) , mobileViewPosition - mWrapper . getHeaderViewsCount ( ) ) ; ( ( BaseAdapter ) mAdapter ) . notifyDataSetChanged ( ) ; mHoverDrawable . shift ( switchView . getHeight ( ) ) ; mSwitchViewAnimator . animateSwitchView ( switchId , translationY ) ; }

Switches the item that is currently being dragged with the item belonging to given id,
by notifying the adapter to swap positions and that the data set has changed.

@param switchView   the {@code View} that should be animated towards the old position of the currently dragging item.
@param switchId     the id of the item that will take the position of the currently dragging item.
@param translationY the distance in pixels the {@code switchView} should animate - i.e. the (positive or negative) height of the {@code View} corresponding to the currently
dragging item.

Switches the item that is currently being dragged with the item belonging to given id by notifying the adapter to swap positions and that the data set has changed .


public void removeActiveIndex(final int index) {
        boolean found = false;
        for (Iterator<AtomicInteger> iterator = mActiveIndexes.iterator(); iterator.hasNext() && !found; ) {
            if (iterator.next().get() == index) {
                iterator.remove();
                found = true;
            }
        }
        if (mActiveIndexes.isEmpty()) {
            insertPending();
        }
    }

public void removeActiveIndex ( final int index ) { boolean found = false ; for ( Iterator < AtomicInteger > iterator = mActiveIndexes . iterator ( ) ; iterator . hasNext ( ) && ! found ; ) { if ( iterator . next ( ) . get ( ) == index ) { iterator . remove ( ) ; found = true ; } } if ( mActiveIndexes . isEmpty ( ) ) { insertPending ( ) ; } }

Clear the active state for given index. Will insert any pending pairs if this call leads to a state where there are no active pairs.

@param index the index to remove.

Clear the active state for given index . Will insert any pending pairs if this call leads to a state where there are no active pairs .


@NonNull
    public Collection<Integer> getActiveIndexes() {
        Collection<Integer> result = new HashSet<>();
        for (AtomicInteger i : mActiveIndexes) {
            result.add(i.get());
        }
        return result;
    }

@ NonNull public Collection < Integer > getActiveIndexes ( ) { Collection < Integer > result = new HashSet <> ( ) ; for ( AtomicInteger i : mActiveIndexes ) { result . add ( i . get ( ) ) ; } return result ; }

Returns a collection of currently active indexes.

Returns a collection of currently active indexes .


@Nullable
    public View getTitleView(final int position) {
        View titleView = null;

        View parentView = findViewForPosition(position);
        if (parentView != null) {
            Object tag = parentView.getTag();
            if (tag instanceof ViewHolder) {
                titleView = ((ViewHolder) tag).titleView;
            }
        }

        return titleView;
    }

@ Nullable public View getTitleView ( final int position ) { View titleView = null ; View parentView = findViewForPosition ( position ) ; if ( parentView != null ) { Object tag = parentView . getTag ( ) ; if ( tag instanceof ViewHolder ) { titleView = ( ( ViewHolder ) tag ) . titleView ; } } return titleView ; }

Return the title view at the specified position.

@param position Index of the view we want.

@return the view if it exist, null otherwise.

Return the title view at the specified position .


@Nullable
    public View getContentView(final int position) {
        View contentView = null;

        View parentView = findViewForPosition(position);
        if (parentView != null) {
            Object tag = parentView.getTag();
            if (tag instanceof ViewHolder) {
                contentView = ((ViewHolder) tag).contentView;
            }
        }

        return contentView;
    }

@ Nullable public View getContentView ( final int position ) { View contentView = null ; View parentView = findViewForPosition ( position ) ; if ( parentView != null ) { Object tag = parentView . getTag ( ) ; if ( tag instanceof ViewHolder ) { contentView = ( ( ViewHolder ) tag ) . contentView ; } } return contentView ; }

Return the content view at the specified position.

@param position Index of the view we want.

@return the view if it exist, null otherwise.

Return the content view at the specified position .


public void expand(final int position) {
        long itemId = getItemId(position);
        if (mExpandedIds.contains(itemId)) {
            return;
        }

        toggle(position);
    }

public void expand ( final int position ) { long itemId = getItemId ( position ) ; if ( mExpandedIds . contains ( itemId ) ) { return ; } toggle ( position ) ; }

Expand the view at given position. Will do nothing if the view is already expanded.

@param position the position to expand.

Expand the view at given position . Will do nothing if the view is already expanded .


public void collapse(final int position) {
        long itemId = getItemId(position);
        if (!mExpandedIds.contains(itemId)) {
            return;
        }

        toggle(position);
    }

public void collapse ( final int position ) { long itemId = getItemId ( position ) ; if ( ! mExpandedIds . contains ( itemId ) ) { return ; } toggle ( position ) ; }

Collapse the view at given position. Will do nothing if the view is already collapsed.

@param position the position to collapse.

Collapse the view at given position . Will do nothing if the view is already collapsed .


@Nullable
    private View getContentParent(final int position) {
        View contentParent = null;

        View parentView = findViewForPosition(position);
        if (parentView != null) {
            Object tag = parentView.getTag();
            if (tag instanceof ViewHolder) {
                contentParent = ((ViewHolder) tag).contentParent;
            }
        }

        return contentParent;
    }

@ Nullable private View getContentParent ( final int position ) { View contentParent = null ; View parentView = findViewForPosition ( position ) ; if ( parentView != null ) { Object tag = parentView . getTag ( ) ; if ( tag instanceof ViewHolder ) { contentParent = ( ( ViewHolder ) tag ) . contentParent ; } } return contentParent ; }

Return the content parent at the specified position.

@param position Index of the view we want.

@return the view if it exist, null otherwise.

Return the content parent at the specified position .


@SuppressWarnings({"MethodMayBeStatic", "UnusedParameters"})
    @NonNull
    protected Animator[] getAdditionalAnimators(@NonNull final View view, @NonNull final ViewGroup parent) {
        return new Animator[]{};
    }

@ SuppressWarnings ( { "MethodMayBeStatic" , "UnusedParameters" } ) @ NonNull protected Animator [ ] getAdditionalAnimators ( @ NonNull final View view , @ NonNull final ViewGroup parent ) { return new Animator [ ] { } ; }

Override this method to provide additional animators on top of the default height and alpha animation.

@param view   The {@link android.view.View} that will get animated.
@param parent The parent that this view will eventually be attached to.

@return a non-null array of Animators.

Override this method to provide additional animators on top of the default height and alpha animation .


@NonNull
    static Bitmap getBitmapFromView(@NonNull final View v) {
        Bitmap bitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        v.draw(canvas);
        return bitmap;
    }

@ NonNull static Bitmap getBitmapFromView ( @ NonNull final View v ) { Bitmap bitmap = Bitmap . createBitmap ( v . getMeasuredWidth ( ) , v . getMeasuredHeight ( ) , Bitmap . Config . ARGB_8888 ) ; Canvas canvas = new Canvas ( bitmap ) ; v . draw ( canvas ) ; return bitmap ; }

Returns a bitmap showing a screenshot of the view passed in.

Returns a bitmap showing a screenshot of the view passed in .


private boolean isDismissable(final int position) {
        if (mListViewWrapper.getAdapter() == null) {
            return false;
        }

        if (mDismissableManager != null) {
            long downId = mListViewWrapper.getAdapter().getItemId(position);
            return mDismissableManager.isDismissable(downId, position);
        }
        return true;
    }

private boolean isDismissable ( final int position ) { if ( mListViewWrapper . getAdapter ( ) == null ) { return false ; } if ( mDismissableManager != null ) { long downId = mListViewWrapper . getAdapter ( ) . getItemId ( position ) ; return mDismissableManager . isDismissable ( downId , position ) ; } return true ; }

Finds out whether the item represented by given position is dismissable.

@param position the position of the item.

@return {@code true} if the item is dismissable, false otherwise.

Finds out whether the item represented by given position is dismissable .


private void reset() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
        }

        mVelocityTracker = null;
        mDownX = 0;
        mDownY = 0;
        mCurrentView = null;
        mSwipingView = null;
        mCurrentPosition = AdapterView.INVALID_POSITION;
        mSwiping = false;
        mCanDismissCurrent = false;
    }

private void reset ( ) { if ( mVelocityTracker != null ) { mVelocityTracker . recycle ( ) ; } mVelocityTracker = null ; mDownX = 0 ; mDownY = 0 ; mCurrentView = null ; mSwipingView = null ; mCurrentPosition = AdapterView . INVALID_POSITION ; mSwiping = false ; mCanDismissCurrent = false ; }

Resets the fields to the initial values, ready to start over.

Resets the fields to the initial values ready to start over .


public void reset() {
        for (int i = 0; i < mAnimators.size(); i++) {
            mAnimators.get(mAnimators.keyAt(i)).cancel();
        }
        mAnimators.clear();
        mFirstAnimatedPosition = -1;
        mLastAnimatedPosition = -1;
        mAnimationStartMillis = -1;
        mShouldAnimate = true;
    }

public void reset ( ) { for ( int i = 0 ; i < mAnimators . size ( ) ; i ++ ) { mAnimators . get ( mAnimators . keyAt ( i ) ) . cancel ( ) ; } mAnimators . clear ( ) ; mFirstAnimatedPosition = - 1 ; mLastAnimatedPosition = - 1 ; mAnimationStartMillis = - 1 ; mShouldAnimate = true ; }

Call this method to reset animation status on all views.

Call this method to reset animation status on all views .


void cancelExistingAnimation(@NonNull final View view) {
        int hashCode = view.hashCode();
        Animator animator = mAnimators.get(hashCode);
        if (animator != null) {
            animator.end();
            mAnimators.remove(hashCode);
        }
    }

void cancelExistingAnimation ( @ NonNull final View view ) { int hashCode = view . hashCode ( ) ; Animator animator = mAnimators . get ( hashCode ) ; if ( animator != null ) { animator . end ( ) ; mAnimators . remove ( hashCode ) ; } }

Cancels any existing animations for given View.

Cancels any existing animations for given View .


private void animateView(final int position, @NonNull final View view, @NonNull final Animator[] animators) {
        if (mAnimationStartMillis == -1) {
            mAnimationStartMillis = SystemClock.uptimeMillis();
        }

        ViewHelper.setAlpha(view, 0);

        AnimatorSet set = new AnimatorSet();
        set.playTogether(animators);
        set.setStartDelay(calculateAnimationDelay(position));
        set.setDuration(mAnimationDurationMillis);
        set.start();

        mAnimators.put(view.hashCode(), set);
    }

private void animateView ( final int position , @ NonNull final View view , @ NonNull final Animator [ ] animators ) { if ( mAnimationStartMillis == - 1 ) { mAnimationStartMillis = SystemClock . uptimeMillis ( ) ; } ViewHelper . setAlpha ( view , 0 ) ; AnimatorSet set = new AnimatorSet ( ) ; set . playTogether ( animators ) ; set . setStartDelay ( calculateAnimationDelay ( position ) ) ; set . setDuration ( mAnimationDurationMillis ) ; set . start ( ) ; mAnimators . put ( view . hashCode ( ) , set ) ; }

Animates given View.

@param view the View that should be animated.


@SuppressLint("NewApi")
    private int calculateAnimationDelay(final int position) {
        int delay;

        int lastVisiblePosition = mListViewWrapper.getLastVisiblePosition();
        int firstVisiblePosition = mListViewWrapper.getFirstVisiblePosition();

        int numberOfItemsOnScreen = lastVisiblePosition - firstVisiblePosition;
        int numberOfAnimatedItems = position - 1 - mFirstAnimatedPosition;

        if (numberOfItemsOnScreen + 1 < numberOfAnimatedItems) {
            delay = mAnimationDelayMillis;

            if (mListViewWrapper.getListView() instanceof GridView && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                int numColumns = ((GridView) mListViewWrapper.getListView()).getNumColumns();
                delay += mAnimationDelayMillis * (position % numColumns);
            }
        } else {
            int delaySinceStart = (position - mFirstAnimatedPosition) * mAnimationDelayMillis;
            delay = Math.max(0, (int) (-SystemClock.uptimeMillis() + mAnimationStartMillis + mInitialDelayMillis + delaySinceStart));
        }
        return delay;
    }

@ SuppressLint ( "NewApi" ) private int calculateAnimationDelay ( final int position ) { int delay ; int lastVisiblePosition = mListViewWrapper . getLastVisiblePosition ( ) ; int firstVisiblePosition = mListViewWrapper . getFirstVisiblePosition ( ) ; int numberOfItemsOnScreen = lastVisiblePosition - firstVisiblePosition ; int numberOfAnimatedItems = position - 1 - mFirstAnimatedPosition ; if ( numberOfItemsOnScreen + 1 < numberOfAnimatedItems ) { delay = mAnimationDelayMillis ; if ( mListViewWrapper . getListView ( ) instanceof GridView && Build . VERSION . SDK_INT >= Build . VERSION_CODES . HONEYCOMB ) { int numColumns = ( ( GridView ) mListViewWrapper . getListView ( ) ) . getNumColumns ( ) ; delay += mAnimationDelayMillis * ( position % numColumns ) ; } } else { int delaySinceStart = ( position - mFirstAnimatedPosition ) * mAnimationDelayMillis ; delay = Math . max ( 0 , ( int ) ( - SystemClock . uptimeMillis ( ) + mAnimationStartMillis + mInitialDelayMillis + delaySinceStart ) ) ; } return delay ; }

Returns the delay in milliseconds after which animation for View with position mLastAnimatedPosition + 1 should start.

Returns the delay in milliseconds after which animation for View with position mLastAnimatedPosition + 1 should start .


@NonNull
    public static Animator[] concatAnimators(@NonNull final Animator[] childAnimators, @NonNull final Animator[] animators, @NonNull final Animator alphaAnimator) {
        Animator[] allAnimators = new Animator[childAnimators.length + animators.length + 1];
        int i;

        for (i = 0; i < childAnimators.length; ++i) {
            allAnimators[i] = childAnimators[i];
        }

        for (Animator animator : animators) {
            allAnimators[i] = animator;
            ++i;
        }

        allAnimators[allAnimators.length - 1] = alphaAnimator;
        return allAnimators;
    }

@ NonNull public static Animator [ ] concatAnimators ( @ NonNull final Animator [ ] childAnimators , @ NonNull final Animator [ ] animators , @ NonNull final Animator alphaAnimator ) { Animator [ ] allAnimators = new Animator [ childAnimators . length + animators . length + 1 ] ; int i ; for ( i = 0 ; i < childAnimators . length ; ++ i ) { allAnimators [ i ] = childAnimators [ i ] ; } for ( Animator animator : animators ) { allAnimators [ i ] = animator ; ++ i ; } allAnimators [ allAnimators . length - 1 ] = alphaAnimator ; return allAnimators ; }


public void handleNonCORS(final HttpServletRequest request,
            final HttpServletResponse response, final FilterChain filterChain)
            throws IOException, ServletException {
        // Let request pass.
        filterChain.doFilter(request, response);
    }

public
void
handleNonCORS
(
final
HttpServletRequest
request
,
final
HttpServletResponse
response
,
final
FilterChain
filterChain
)
throws
IOException
,
ServletException
{
// Let request pass.
filterChain
.
doFilter
(
request
,
response
)
;
}

Handles a request, that's not a CORS request, but is a valid request i.e.
it is not a cross-origin request. This implementation, just forwards the
request down the filter chain.

@param request
The {@link HttpServletRequest} object.
@param response
The {@link HttpServletResponse} object.
@param filterChain
The {@link FilterChain} object.
@throws IOException
@throws ServletException

Handles a request that s not a CORS request but is a valid request i . e . it is not a cross - origin request . This implementation just forwards the request down the filter chain .


@Override
    public void addStreamOfLiteralWords(Buffer buffer, int start, int number) {
        for(int x = start; x < start + number ; ++x)
           if(buffer.getWord(x)!=0) throw nonEmptyException;
    }

@ Override public void addStreamOfLiteralWords ( Buffer buffer , int start , int number ) { for ( int x = start ; x < start + number ; ++ x ) if ( buffer . getWord ( x ) != 0 ) throw nonEmptyException ; }

throws a NonEmptyException exception when number is greater than 0


public static void materialize(final IteratingRLW i,
                                   final BitmapStorage c) {
        while (true) {
            if (i.getRunningLength() > 0) {
                c.addStreamOfEmptyWords(i.getRunningBit(), i.getRunningLength());
            }
            int il = i.getNumberOfLiteralWords();
            for (int k = 0; k < il ; ++k)
                c.addWord(i.getLiteralWordAt(k));
            if (!i.next())
                break;
        }
    }

public static void materialize ( final IteratingRLW i , final BitmapStorage c ) { while ( true ) { if ( i . getRunningLength ( ) > 0 ) { c . addStreamOfEmptyWords ( i . getRunningBit ( ) , i . getRunningLength ( ) ) ; } int il = i . getNumberOfLiteralWords ( ) ; for ( int k = 0 ; k < il ; ++ k ) c . addWord ( i . getLiteralWordAt ( k ) ) ; if ( ! i . next ( ) ) break ; } }

Generate a bitmap from an iterator.

@param i iterator we wish to materialize
@param c where we write


public T poll() {
        T ans = this.a[1];
        this.a[1] = this.a[this.lastIndex--];
        percolateDown(1);
        return ans;
    }

public T poll ( ) { T ans = this . a [ 1 ] ; this . a [ 1 ] = this . a [ this . lastIndex -- ] ; percolateDown ( 1 ) ; return ans ; }

Remove the element on top of the heap

@return the element being removed


private void resizeBuffer(int number) {
        int size = newSizeInWords(number);
        if (size >= this.buffer.length) {
            long oldBuffer[] = this.buffer;
            this.buffer = new long[size];
            System.arraycopy(oldBuffer, 0, this.buffer, 0, oldBuffer.length);
        }
	}

private void resizeBuffer ( int number ) { int size = newSizeInWords ( number ) ; if ( size >= this . buffer . length ) { long oldBuffer [ ] = this . buffer ; this . buffer = new long [ size ] ; System . arraycopy ( oldBuffer , 0 , this . buffer , 0 , oldBuffer . length ) ; } }

Resizes the buffer if the number of words to add exceeds the buffer capacity.
@param number the number of words to add

Resizes the buffer if the number of words to add exceeds the buffer capacity .


private int newSizeInWords(int number) {
        int size = this.actualSizeInWords + number;
        if (size >= this.buffer.length) {
            if (size < 32768)
                size = size * 2;
            else if (size * 3 / 2 < size) // overflow
                size = Integer.MAX_VALUE;
            else
                size = size * 3 / 2;
        }
        return size;
    }

private
int
newSizeInWords
(
int
number
)
{
int
size
=
this
.
actualSizeInWords
+
number
;
if
(
size
>=
this
.
buffer
.
length
)
{
if
(
size
<
32768
)
size
=
size
*
2
;
else
if
(
size
*
3
/
2
<
size
)
// overflow
size
=
Integer
.
MAX_VALUE
;
else
size
=
size
*
3
/
2
;
}
return
size
;
}

Returns the resulting buffer size in words given the number of words to add.
@param number the number of words to add

Returns the resulting buffer size in words given the number of words to add .


public static EWAHCompressedBitmap32 xor(final EWAHCompressedBitmap32... bitmaps) {
        PriorityQueue<EWAHCompressedBitmap32> pq = new PriorityQueue<EWAHCompressedBitmap32>(bitmaps.length,
                new Comparator<EWAHCompressedBitmap32>() {
                    @Override
                    public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) {
                        return a.sizeInBytes()
                                - b.sizeInBytes();
                    }
                }
        );
        Collections.addAll(pq, bitmaps);
        if(pq.isEmpty()) return new EWAHCompressedBitmap32();
        while (pq.size() > 1) {
            EWAHCompressedBitmap32 x1 = pq.poll();
            EWAHCompressedBitmap32 x2 = pq.poll();
            pq.add(x1.xor(x2));
        }
        return pq.poll();
    }

public static EWAHCompressedBitmap32 xor ( final EWAHCompressedBitmap32 ... bitmaps ) { PriorityQueue < EWAHCompressedBitmap32 > pq = new PriorityQueue < EWAHCompressedBitmap32 > ( bitmaps . length , new Comparator < EWAHCompressedBitmap32 > ( ) { @ Override public int compare ( EWAHCompressedBitmap32 a , EWAHCompressedBitmap32 b ) { return a . sizeInBytes ( ) - b . sizeInBytes ( ) ; } } ) ; Collections . addAll ( pq , bitmaps ) ; if ( pq . isEmpty ( ) ) return new EWAHCompressedBitmap32 ( ) ; while ( pq . size ( ) > 1 ) { EWAHCompressedBitmap32 x1 = pq . poll ( ) ; EWAHCompressedBitmap32 x2 = pq . poll ( ) ; pq . add ( x1 . xor ( x2 ) ) ; } return pq . poll ( ) ; }

Simple algorithm that computes the XOR aggregate.

@param bitmaps input bitmaps
@return new bitmap containing the aggregate

Simple algorithm that computes the XOR aggregate .


@Override
    public void addStreamOfLiteralWords(Buffer32 buffer, int start, int number) {
        for (int i = start; i < start + number; i++) {
            addLiteralWord(buffer.getWord(i));
        }
    }

@ Override public void addStreamOfLiteralWords ( Buffer32 buffer , int start , int number ) { for ( int i = start ; i < start + number ; i ++ ) { addLiteralWord ( buffer . getWord ( i ) ) ; } }

virtually add several literal words.

@param buffer the buffer wrapping the literal words
@param start  the starting point in the array
@param number the number of literal words to add


public final void fillWithLiterals(final List<EWAHPointer32> container) {
        for (int k = this.litwlist.nextSetBit(0); k >= 0; k = this.litwlist
                .nextSetBit(k + 1)) {
            container.add(this.rw[k]);
        }
    }

public final void fillWithLiterals ( final List < EWAHPointer32 > container ) { for ( int k = this . litwlist . nextSetBit ( 0 ) ; k >= 0 ; k = this . litwlist . nextSetBit ( k + 1 ) ) { container . add ( this . rw [ k ] ) ; } }

append to the list the literal words as EWAHPointer

@param container where we write


public BitSet asBitSet() {
  	BitSet bs = new BitSet(this.size());
  	this.data.rewind();
  	this.data.get(bs.data, 0, bs.data.length);
		return bs;
  }

public BitSet asBitSet ( ) { BitSet bs = new BitSet ( this . size ( ) ) ; this . data . rewind ( ) ; this . data . get ( bs . data , 0 , bs . data . length ) ; return bs ; }

Get a copy of this ImmutableBitSet as a mutable BitSet.
@return a copy

Get a copy of this ImmutableBitSet as a mutable BitSet .


public int cardinality() {
      int sum = 0;
      int length = this.data.limit();
      for(int k = 0; k < length; ++k)
          sum += Long.bitCount(this.data.get(k));
      return sum;
  }

public int cardinality ( ) { int sum = 0 ; int length = this . data . limit ( ) ; for ( int k = 0 ; k < length ; ++ k ) sum += Long . bitCount ( this . data . get ( k ) ) ; return sum ; }

Compute the number of bits set to 1

@return the number of bits


public boolean empty() {
    int length = this.data.limit();
    for(int k = 0; k < length; ++k)
          if (this.data.get(k) != 0) return false;
      return true;
  }

public boolean empty ( ) { int length = this . data . limit ( ) ; for ( int k = 0 ; k < length ; ++ k ) if ( this . data . get ( k ) != 0 ) return false ; return true ; }

Check whether a bitset contains a set bit.

@return true if no set bit is found

Check whether a bitset contains a set bit .


public IntIterator intIterator() {
      return new IntIterator() {
          @Override
          public boolean hasNext() {
              return this.i >= 0;
          }

          @Override
          public int next() {
              this.j = this.i;
              this.i = ImmutableBitSet.this.nextSetBit(this.i + 1);
              return this.j;
          }

          private int i = ImmutableBitSet.this.nextSetBit(0);

          private int j;

      };
  }

public IntIterator intIterator ( ) { return new IntIterator ( ) { @ Override public boolean hasNext ( ) { return this . i >= 0 ; } @ Override public int next ( ) { this . j = this . i ; this . i = ImmutableBitSet . this . nextSetBit ( this . i + 1 ) ; return this . j ; } private int i = ImmutableBitSet . this . nextSetBit ( 0 ) ; private int j ; } ; }

Iterate over the set bits

@return an iterator


public boolean intersects(BitSet bs) {
      for (int k = 0; k < Math.min(this.data.limit(), bs.data.length); ++k) {
          if ((this.data.get(k) & bs.data[k]) != 0) return true;
      }
      return false;
  }

public boolean intersects ( BitSet bs ) { for ( int k = 0 ; k < Math . min ( this . data . limit ( ) , bs . data . length ) ; ++ k ) { if ( ( this . data . get ( k ) & bs . data [ k ] ) != 0 ) return true ; } return false ; }

Checks whether two bitsets intersect.

@param bs other bitset
@return true if they have a non-empty intersection (result of AND)


public IntIterator unsetIntIterator() {
      return new IntIterator() {
          @Override
          public boolean hasNext() {
              return this.i >= 0;
          }

          @Override
          public int next() {
              this.j = this.i;
              this.i = ImmutableBitSet.this.nextUnsetBit(this.i + 1);
              return this.j;
          }

          private int i = ImmutableBitSet.this.nextUnsetBit(0);

          private int j;
      };
  }

public IntIterator unsetIntIterator ( ) { return new IntIterator ( ) { @ Override public boolean hasNext ( ) { return this . i >= 0 ; } @ Override public int next ( ) { this . j = this . i ; this . i = ImmutableBitSet . this . nextUnsetBit ( this . i + 1 ) ; return this . j ; } private int i = ImmutableBitSet . this . nextUnsetBit ( 0 ) ; private int j ; } ; }

Iterate over the unset bits

@return an iterator


public void parseNextRun() {
        if ((this.isLiteral)
                || (this.iterator.getNumberOfLiteralWords() == 0)) {
            // no choice, must load next runs
            this.iterator.discardFirstWords(this.iterator.size());
            if (this.iterator.getRunningLength() > 0) {
                this.endrun += this.iterator
                        .getRunningLength();
                this.isLiteral = false;
                this.value = this.iterator.getRunningBit();
            } else if (this.iterator.getNumberOfLiteralWords() > 0) {
                this.isLiteral = true;
                this.endrun += this.iterator
                        .getNumberOfLiteralWords();
            } else {
                this.dead = true;
            }

        } else {
            this.isLiteral = true;
            this.endrun += this.iterator.getNumberOfLiteralWords();
        }

    }

public
void
parseNextRun
(
)
{
if
(
(
this
.
isLiteral
)
||
(
this
.
iterator
.
getNumberOfLiteralWords
(
)
==
0
)
)
{
// no choice, must load next runs
this
.
iterator
.
discardFirstWords
(
this
.
iterator
.
size
(
)
)
;
if
(
this
.
iterator
.
getRunningLength
(
)
>
0
)
{
this
.
endrun
+=
this
.
iterator
.
getRunningLength
(
)
;
this
.
isLiteral
=
false
;
this
.
value
=
this
.
iterator
.
getRunningBit
(
)
;
}
else
if
(
this
.
iterator
.
getNumberOfLiteralWords
(
)
>
0
)
{
this
.
isLiteral
=
true
;
this
.
endrun
+=
this
.
iterator
.
getNumberOfLiteralWords
(
)
;
}
else
{
this
.
dead
=
true
;
}
}
else
{
this
.
isLiteral
=
true
;
this
.
endrun
+=
this
.
iterator
.
getNumberOfLiteralWords
(
)
;
}
}


public void open() {
    state = State.OPENED;
    showIcons(true);

    animator[LEFT].setFloatValues(button[LEFT], 0);
    animator[RIGHT].setFloatValues(button[RIGHT], width);
    animator[RADIUS].setFloatValues(button[RADIUS], 0);
    animator[TOP].setFloatValues(button[TOP], 0);
    animator[BOTTOM].setFloatValues(button[BOTTOM], height);

    animatorSet.cancel();
    animatorSet.start();
    if (iconOpenedDrawable instanceof Animatable) {
      ((Animatable) iconOpenedDrawable).start();
    }
    ViewGroup parentView = (ViewGroup) TapBarMenu.this.getParent();
    this.animate()
        .y(menuAnchor == MENU_ANCHOR_BOTTOM ? parentView.getBottom() - height : 0)
            .setDuration(animationDuration)
            .setInterpolator(DECELERATE_INTERPOLATOR)
            .start();
  }

public void open ( ) { state = State . OPENED ; showIcons ( true ) ; animator [ LEFT ] . setFloatValues ( button [ LEFT ] , 0 ) ; animator [ RIGHT ] . setFloatValues ( button [ RIGHT ] , width ) ; animator [ RADIUS ] . setFloatValues ( button [ RADIUS ] , 0 ) ; animator [ TOP ] . setFloatValues ( button [ TOP ] , 0 ) ; animator [ BOTTOM ] . setFloatValues ( button [ BOTTOM ] , height ) ; animatorSet . cancel ( ) ; animatorSet . start ( ) ; if ( iconOpenedDrawable instanceof Animatable ) { ( ( Animatable ) iconOpenedDrawable ) . start ( ) ; } ViewGroup parentView = ( ViewGroup ) TapBarMenu . this . getParent ( ) ; this . animate ( ) . y ( menuAnchor == MENU_ANCHOR_BOTTOM ? parentView . getBottom ( ) - height : 0 ) . setDuration ( animationDuration ) . setInterpolator ( DECELERATE_INTERPOLATOR ) . start ( ) ; }


public void close() {
    updateDimensions(width, height);
    state = State.CLOSED;
    showIcons(false);

    animator[LEFT].setFloatValues(0, button[LEFT]);
    animator[RIGHT].setFloatValues(width, button[RIGHT]);
    animator[RADIUS].setFloatValues(0, button[RADIUS]);
    animator[TOP].setFloatValues(0, button[TOP]);
    animator[BOTTOM].setFloatValues(height, button[BOTTOM]);

    animatorSet.cancel();
    animatorSet.start();
    if (iconClosedDrawable instanceof Animatable) {
      ((Animatable) iconClosedDrawable).start();
    }
    this.animate()
            .y(yPosition)
            .setDuration(animationDuration)
            .setInterpolator(DECELERATE_INTERPOLATOR)
            .start();
  }

public void close ( ) { updateDimensions ( width , height ) ; state = State . CLOSED ; showIcons ( false ) ; animator [ LEFT ] . setFloatValues ( 0 , button [ LEFT ] ) ; animator [ RIGHT ] . setFloatValues ( width , button [ RIGHT ] ) ; animator [ RADIUS ] . setFloatValues ( 0 , button [ RADIUS ] ) ; animator [ TOP ] . setFloatValues ( 0 , button [ TOP ] ) ; animator [ BOTTOM ] . setFloatValues ( height , button [ BOTTOM ] ) ; animatorSet . cancel ( ) ; animatorSet . start ( ) ; if ( iconClosedDrawable instanceof Animatable ) { ( ( Animatable ) iconClosedDrawable ) . start ( ) ; } this . animate ( ) . y ( yPosition ) . setDuration ( animationDuration ) . setInterpolator ( DECELERATE_INTERPOLATOR ) . start ( ) ; }


public void setMenuBackgroundColor(int colorResId) {
    backgroundColor = ContextCompat.getColor(getContext(), colorResId);
    paint.setColor(backgroundColor);
    invalidate();
  }

public void setMenuBackgroundColor ( int colorResId ) { backgroundColor = ContextCompat . getColor ( getContext ( ) , colorResId ) ; paint . setColor ( backgroundColor ) ; invalidate ( ) ; }

Sets TapBarMenu's background color from given resource.
@param colorResId Color resource id. For example: R.color.holo_blue_light

Sets TapBarMenu s background color from given resource .


private int[] fetchDatabaseNameRangeIndexFromURLForH2FileMode(String url) {
    int fileLabelIndex = url.indexOf(FILE_MODE_FLAG);
    int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
    if (parameterLabelIndex == -1) {
      parameterLabelIndex = url.length();
    }

    if (fileLabelIndex != -1) {
      return new int[]{fileLabelIndex + FILE_MODE_FLAG.length() + 1, parameterLabelIndex};
    } else {
      return null;
    }
  }

Fetch range index that the database name from connection url if H2 database running with file
mode.

@return range index that the database name.

Fetch range index that the database name from connection url if H2 database running with file mode .


private int[] fetchDatabaseNameRangeIndexFromURLForH2MemMode(String url) {
    int fileLabelIndex = url.indexOf(MEMORY_MODE_FLAG);
    int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
    if (parameterLabelIndex == -1) {
      parameterLabelIndex = url.length();
    }

    if (fileLabelIndex != -1) {
      return new int[]{fileLabelIndex + MEMORY_MODE_FLAG.length() + 1, parameterLabelIndex};
    } else {
      return null;
    }
  }

Fetch range index that the database name from connection url if H2 database running with memory
mode.

@return range index that the database name.

Fetch range index that the database name from connection url if H2 database running with memory mode .


public static ConnectionInfo parser(String url) {
    if (null == url) {
      return ConnectionInfo.UNKNOWN_CONNECTION_INFO;
    }
    String lowerCaseUrl = url.toLowerCase();
    ConnectionURLParser parser = findURLParser(lowerCaseUrl);
    if (parser == null) {
      return ConnectionInfo.UNKNOWN_CONNECTION_INFO;
    }
    try {
      return parser.parse(url);
    } catch (Exception e) {
      log.log(Level.WARNING, "error occurs when paring jdbc url");
    }
    return ConnectionInfo.UNKNOWN_CONNECTION_INFO;
  }

public
static
ConnectionInfo
parser
(
String
url
)
{
if
(
==
url
)
{
return
ConnectionInfo
.
UNKNOWN_CONNECTION_INFO
;
}
String
lowerCaseUrl
=
url
.
toLowerCase
(
)
;
ConnectionURLParser
parser
=
findURLParser
(
lowerCaseUrl
)
;
if
(
parser
==
)
{
return
ConnectionInfo
.
UNKNOWN_CONNECTION_INFO
;
}
try
{
return
parser
.
parse
(
url
)
;
}
catch
(
Exception
e
)
{
log
.
log
(
Level
.
WARNING
,
"error occurs when paring jdbc url"
)
;
}
return
ConnectionInfo
.
UNKNOWN_CONNECTION_INFO
;
}


public static void registerConnectionParser(String urlPrefix, ConnectionURLParser parser) {
    if (null == urlPrefix || parser == null) {
      throw new IllegalArgumentException("urlPrefix and parser can not be null");
    }
    parserRegister.put(urlPrefix.toLowerCase(), parser);
  }

public
static
void
registerConnectionParser
(
String
urlPrefix
,
ConnectionURLParser
parser
)
{
if
(
==
urlPrefix
||
parser
==
)
{
throw
new
IllegalArgumentException
(
"urlPrefix and parser can not be null"
)
;
}
parserRegister
.
put
(
urlPrefix
.
toLowerCase
(
)
,
parser
)
;
}

register new ConnectionURLParser. Can override existing parser.

register new ConnectionURLParser . Can override existing parser .


protected String fetchDatabaseNameFromURL(String url) {
    URLLocation hostsLocation = fetchDatabaseNameIndexRange(url);
    return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
  }

protected String fetchDatabaseNameFromURL ( String url ) { URLLocation hostsLocation = fetchDatabaseNameIndexRange ( url ) ; return url . substring ( hostsLocation . startIndex ( ) , hostsLocation . endIndex ( ) ) ; }

Fetch database name from connection url.

@return database name.

Fetch database name from connection url .


public static void run(final Context context, final Class<?> daemonServiceClazz,
	                       final int interval) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				Command.install(context, BIN_DIR_NAME, DAEMON_BIN_NAME);
				start(context, daemonServiceClazz, interval);
			}
		}).start();
	}

public static void run ( final Context context , final Class < ? > daemonServiceClazz , final int interval ) { new Thread ( new Runnable ( ) { @ Override public void run ( ) { Command . install ( context , BIN_DIR_NAME , DAEMON_BIN_NAME ) ; start ( context , daemonServiceClazz , interval ) ; } } ) . start ( ) ; }

Run daemon process.

@param context            context
@param daemonServiceClazz the name of daemon service class
@param interval           the interval to check


private static void copyFile(File file, InputStream is, String mode)
		throws IOException, InterruptedException {
		final String abspath = file.getAbsolutePath();
		final FileOutputStream out = new FileOutputStream(file);
		byte buf[] = new byte[1024];
		int len;
		while ((len = is.read(buf)) > 0) {
			out.write(buf, 0, len);
		}

		out.close();
		is.close();

		Runtime.getRuntime().exec("chmod " + mode + " " + abspath).waitFor();
	}

private
static
void
copyFile
(
File
file
,
InputStream
is
,
String
mode
)
throws
IOException
,
InterruptedException
{
final
String
abspath
=
file
.
getAbsolutePath
(
)
;
final
FileOutputStream
out
=
new
FileOutputStream
(
file
)
;
byte
buf
[
]
=
new
byte
[
1024
]
;
int
len
;
while
(
(
len
=
is
.
read
(
buf
)
)
>
0
)
{
out
.
write
(
buf
,
0
,
len
)
;
}
out
.
close
(
)
;
is
.
close
(
)
;
Runtime
.
getRuntime
(
)
.
exec
(
"chmod "
+
mode
+
" "
+
abspath
)
.
waitFor
(
)
;
}


public static void copyAssets(Context context, String assetsFilename, File file, String mode)
		throws IOException, InterruptedException {
		AssetManager manager = context.getAssets();
		final InputStream is = manager.open(assetsFilename);
		copyFile(file, is, mode);
	}

public static void copyAssets ( Context context , String assetsFilename , File file , String mode ) throws IOException , InterruptedException { AssetManager manager = context . getAssets ( ) ; final InputStream is = manager . open ( assetsFilename ) ; copyFile ( file , is , mode ) ; }

copy file in assets into destination file

@param context        context
@param assetsFilename file name in assets
@param file           the file to copy to
@param mode           mode of file
@throws IOException
@throws InterruptedException


@SuppressWarnings("deprecation")
	public static boolean install(Context context, String destDir, String filename) {
		String binaryDir = "armeabi";

		String abi = Build.CPU_ABI;
		if (abi.startsWith("armeabi-v7a")) {
			binaryDir = "armeabi-v7a";
		} else if (abi.startsWith("x86")) {
			binaryDir = "x86";
		}

		/* for different platform */
		String assetfilename = binaryDir + File.separator + filename;

		try {
			File f = new File(context.getDir(destDir, Context.MODE_PRIVATE), filename);
			if (f.exists()) {
				Log.d(TAG, "binary has existed");
				return false;
			}

			copyAssets(context, assetfilename, f, "0755");
			return true;
		} catch (Exception e) {
			Log.e(TAG, "installBinary failed: " + e.getMessage());
			return false;
		}
	}

@
SuppressWarnings
(
"deprecation"
)
public
static
boolean
install
(
Context
context
,
String
destDir
,
String
filename
)
{
String
binaryDir
=
"armeabi"
;
String
abi
=
Build
.
CPU_ABI
;
if
(
abi
.
startsWith
(
"armeabi-v7a"
)
)
{
binaryDir
=
"armeabi-v7a"
;
}
else
if
(
abi
.
startsWith
(
"x86"
)
)
{
binaryDir
=
"x86"
;
}
/* for different platform */
String
assetfilename
=
binaryDir
+
File
.
separator
+
filename
;
try
{
File
f
=
new
File
(
context
.
getDir
(
destDir
,
Context
.
MODE_PRIVATE
)
,
filename
)
;
if
(
f
.
exists
(
)
)
{
Log
.
d
(
TAG
,
"binary has existed"
)
;
return
false
;
}
copyAssets
(
context
,
assetfilename
,
f
,
"0755"
)
;
return
true
;
}
catch
(
Exception
e
)
{
Log
.
e
(
TAG
,
"installBinary failed: "
+
e
.
getMessage
(
)
)
;
return
false
;
}
}

Install specified binary into destination directory.

@param context  context
@param destDir  destionation directory
@param filename filename of binary
@return true if install successfully, otherwise return false

Install specified binary into destination directory .


private void handleMissingFields()
    {
        MissingFieldHandler missingFieldHandler = reader.getMissingFieldHandler();
        if (missingFieldHandler != null)
        {
            for (Missingfields mf : missingFields)
            {
                missingFieldHandler.fieldMissing(mf.target, mf.fieldName, mf.value);
            }
        }//else no handler so ignore.
    }

private
void
handleMissingFields
(
)
{
MissingFieldHandler
missingFieldHandler
=
reader
.
getMissingFieldHandler
(
)
;
if
(
missingFieldHandler
!=
)
{
for
(
Missingfields
mf
:
missingFields
)
{
missingFieldHandler
.
fieldMissing
(
mf
.
target
,
mf
.
fieldName
,
mf
.
value
)
;
}
}
//else no handler so ignore.
}

calls the missing field handler if any for each recorded missing field.

calls the missing field handler if any for each recorded missing field .


private Object getEnum(Class c, JsonObject jsonObj)
    {
        try
        {
            return Enum.valueOf(c, (String) jsonObj.get("name"));
        }
        catch (Exception e)
        {   // In case the enum class has it's own 'name' member variable (shadowing the 'name' variable on Enum)
            return Enum.valueOf(c, (String) jsonObj.get("java.lang.Enum.name"));
        }
    }

Fetch enum value (may need to try twice, due to potential 'name' field shadowing by enum subclasses

Fetch enum value ( may need to try twice due to potential name field shadowing by enum subclasses


protected void patchUnresolvedReferences()
    {
        Iterator i = unresolvedRefs.iterator();
        while (i.hasNext())
        {
            UnresolvedReference ref = (UnresolvedReference) i.next();
            Object objToFix = ref.referencingObj.target;
            JsonObject objReferenced = reader.getObjectsRead().get(ref.refId);

            if (ref.index >= 0)
            {    // Fix []'s and Collections containing a forward reference.
                if (objToFix instanceof List)
                {   // Patch up Indexable Collections
                    List list = (List) objToFix;
                    list.set(ref.index, objReferenced.target);
                }
                else if (objToFix instanceof Collection)
                {   // Add element (since it was not indexable, add it to collection)
                    Collection col = (Collection) objToFix;
                    col.add(objReferenced.target);
                }
                else
                {
                    Array.set(objToFix, ref.index, objReferenced.target);        // patch array element here
                }
            }
            else
            {    // Fix field forward reference
                Field field = MetaUtils.getField(objToFix.getClass(), ref.field);
                if (field != null)
                {
                    try
                    {
                        field.set(objToFix, objReferenced.target);               // patch field here
                    }
                    catch (Exception e)
                    {
                        throw new JsonIoException("Error setting field while resolving references '" + field.getName() + "', @ref = " + ref.refId, e);
                    }
                }
            }

            i.remove();
        }
    }

For all fields where the value was "@ref":"n" where 'n' was the id of an object
that had not yet been encountered in the stream, make the final substitution.


public void traverseFields(final Deque<JsonObject<String, Object>> stack, final JsonObject<String, Object> jsonObj)
    {
        final Object target = jsonObj.target;
        for (Map.Entry<String, Object> e : jsonObj.entrySet())
        {
            final String fieldName = e.getKey();
            final Field field = (target != null) ? MetaUtils.getField(target.getClass(), fieldName) : null;
            final Object rhs = e.getValue();

            if (rhs == null)
            {
                jsonObj.put(fieldName, null);
            }
            else if (rhs == JsonParser.EMPTY_OBJECT)
            {
                jsonObj.put(fieldName, new JsonObject());
            }
            else if (rhs.getClass().isArray())
            {   // RHS is an array
                // Trace the contents of the array (so references inside the array and into the array work)
                JsonObject<String, Object> jsonArray = new JsonObject<String, Object>();
                jsonArray.put("@items", rhs);
                stack.addFirst(jsonArray);

                // Assign the array directly to the Map key (field name)
                jsonObj.put(fieldName, rhs);
            }
            else if (rhs instanceof JsonObject)
            {
                JsonObject<String, Object> jObj = (JsonObject) rhs;

                if (field != null && MetaUtils.isLogicalPrimitive(field.getType()))
                {
                    jObj.put("value", MetaUtils.convert(field.getType(), jObj.get("value")));
                    continue;
                }
                Long refId = jObj.getReferenceId();

                if (refId != null)
                {    // Correct field references
                    JsonObject refObject = getReferencedObj(refId);
                    jsonObj.put(fieldName, refObject);    // Update Map-of-Maps reference
                }
                else
                {
                    stack.addFirst(jObj);
                }
            }
            else if (field != null)
            {   // The code below is 'upgrading' the RHS values in the passed in JsonObject Map
                // by using the @type class name (when specified and exists), to coerce the vanilla
                // JSON values into the proper types defined by the class listed in @type.  This is
                // a cool feature of json-io, that even when reading a map-of-maps JSON file, it will
                // improve the final types of values in the maps RHS, to be of the field type that
                // was optionally specified in @type.
                final Class fieldType = field.getType();
                if (MetaUtils.isPrimitive(fieldType) || BigDecimal.class.equals(fieldType) || BigInteger.class.equals(fieldType) || Date.class.equals(fieldType))
                {
                    jsonObj.put(fieldName, MetaUtils.convert(fieldType, rhs));
                }
                else if (rhs instanceof String)
                {
                    if (fieldType != String.class && fieldType != StringBuilder.class && fieldType != StringBuffer.class)
                    {
                        if ("".equals(((String)rhs).trim()))
                        {   // Allow "" to null out a non-String field on the inbound JSON
                            jsonObj.put(fieldName, null);
                        }
                    }
                }
            }
        }
        jsonObj.target = null;  // don't waste space (used for typed return, not for Map return)
    }

Walk the JsonObject fields and perform necessary substitutions so that all references matched up.
This code patches @ref and @id pairings up, in the 'Map of Map' mode.  Where the JSON may contain
an @id of an object which can have more than one @ref to it, this code will make sure that each
@ref (value side of the Map associated to a given field name) will be pointer to the appropriate Map
instance.
@param stack   Stack (Deque) used for graph traversal.
@param jsonObj a Map-of-Map representation of the current object being examined (containing all fields).

Walk the JsonObject fields and perform necessary substitutions so that all references matched up . This code patches


public static Object jsonToJava(String json, Map<String, Object> optionalArgs)
    {
        if (optionalArgs == null)
        {
            optionalArgs = new HashMap<String, Object>();
            optionalArgs.put(USE_MAPS, false);
        }
        if (!optionalArgs.containsKey(USE_MAPS))
        {
            optionalArgs.put(USE_MAPS, false);
        }
        JsonReader jr = new JsonReader(json, optionalArgs);
        Object obj = jr.readObject();
        jr.close();
        return obj;
    }

public static Object jsonToJava ( String json , Map < String , Object > optionalArgs ) { if ( optionalArgs == null ) { optionalArgs = new HashMap < String , Object > ( ) ; optionalArgs . put ( USE_MAPS , false ) ; } if ( ! optionalArgs . containsKey ( USE_MAPS ) ) { optionalArgs . put ( USE_MAPS , false ) ; } JsonReader jr = new JsonReader ( json , optionalArgs ) ; Object obj = jr . readObject ( ) ; jr . close ( ) ; return obj ; }

Convert the passed in JSON string into a Java object graph.

@param json String JSON input
@param optionalArgs Map of optional parameters to control parsing.  See readme file for details.
@return Java object graph matching JSON input

Convert the passed in JSON string into a Java object graph .


public Object jsonObjectsToJava(JsonObject root)
    {
        getArgs().put(USE_MAPS, false);
        return convertParsedMapsToJava(root);
    }

public Object jsonObjectsToJava ( JsonObject root ) { getArgs ( ) . put ( USE_MAPS , false ) ; return convertParsedMapsToJava ( root ) ; }

Convert a root JsonObject that represents parsed JSON, into
an actual Java object.
@param root JsonObject instance that was the root object from the
JSON input that was parsed in an earlier call to JsonReader.
@return a typed Java instance that was serialized into JSON.

Convert a root JsonObject that represents parsed JSON into an actual Java object .


public void traverseFields(final Deque<JsonObject<String, Object>> stack, final JsonObject<String, Object> jsonObj)
    {
        final Object javaMate = jsonObj.target;
        final Iterator<Map.Entry<String, Object>> i = jsonObj.entrySet().iterator();
        final Class cls = javaMate.getClass();

        while (i.hasNext())
        {
            Map.Entry<String, Object> e = i.next();
            String key = e.getKey();
            final Field field = MetaUtils.getField(cls, key);
            Object rhs = e.getValue();
            if (field != null)
            {
                assignField(stack, jsonObj, field, rhs);
            }
            else if (missingFieldHandler != null)
            {
                handleMissingField(stack, jsonObj, rhs, key);
            }//else no handler so ignor.
        }
    }

public
void
traverseFields
(
final
Deque
<
JsonObject
<
String
,
Object
>
>
stack
,
final
JsonObject
<
String
,
Object
>
jsonObj
)
{
final
Object
javaMate
=
jsonObj
.
target
;
final
Iterator
<
Map
.
Entry
<
String
,
Object
>
>
i
=
jsonObj
.
entrySet
(
)
.
iterator
(
)
;
final
Class
cls
=
javaMate
.
getClass
(
)
;
while
(
i
.
hasNext
(
)
)
{
Map
.
Entry
<
String
,
Object
>
e
=
i
.
next
(
)
;
String
key
=
e
.
getKey
(
)
;
final
Field
field
=
MetaUtils
.
getField
(
cls
,
key
)
;
Object
rhs
=
e
.
getValue
(
)
;
if
(
field
!=
)
{
assignField
(
stack
,
jsonObj
,
field
,
rhs
)
;
}
else
if
(
missingFieldHandler
!=
)
{
handleMissingField
(
stack
,
jsonObj
,
rhs
,
key
)
;
}
//else no handler so ignor.
}
}

Walk the Java object fields and copy them from the JSON object to the Java object, performing
any necessary conversions on primitives, or deep traversals for field assignments to other objects,
arrays, Collections, or Maps.
@param stack   Stack (Deque) used for graph traversal.
@param jsonObj a Map-of-Map representation of the current object being examined (containing all fields).

Walk the Java object fields and copy them from the JSON object to the Java object performing any necessary conversions on primitives or deep traversals for field assignments to other objects arrays Collections or Maps .


private void storeMissingField(Object target, String missingField, Object value)
    {
        missingFields.add(new Missingfields(target, missingField, value));
    }

private void storeMissingField ( Object target , String missingField , Object value ) { missingFields . add ( new Missingfields ( target , missingField , value ) ) ; }

stores the missing field and their values to call back the handler at the end of the resolution, cause some
reference may need to be resolved later.

stores the missing field and their values to call back the handler at the end of the resolution cause some reference may need to be resolved later .


public static Class getRawType(final Type t)
    {
        if (t instanceof ParameterizedType)
        {
            ParameterizedType pType = (ParameterizedType) t;

            if (pType.getRawType() instanceof Class)
            {
                return (Class) pType.getRawType();
            }
        }
        return null;
    }

public static Class getRawType ( final Type t ) { if ( t instanceof ParameterizedType ) { ParameterizedType pType = ( ParameterizedType ) t ; if ( pType . getRawType ( ) instanceof Class ) { return ( Class ) pType . getRawType ( ) ; } } return null ; }

Given the passed in Type t, return the raw type of it, if the passed in value is a ParameterizedType.
@param t Type to attempt to get raw type from.
@return Raw type obtained from the passed in parameterized type or null if T is not a ParameterizedType

Given the passed in Type t return the raw type of it if the passed in value is a ParameterizedType .


private Object readArray(JsonObject object) throws IOException
    {
        final List<Object> array = new ArrayList();

        while (true)
        {
            final Object o = readValue(object);
            if (o != EMPTY_ARRAY)
            {
                array.add(o);
            }
            final int c = skipWhitespaceRead();

            if (c == ']')
            {
                break;
            }
            else if (c != ',')
            {
                error("Expected ',' or ']' inside array");
            }
        }

        return array.toArray();
    }

private
Object
readArray
(
JsonObject
object
)
throws
IOException
{
final
List
<
Object
>
array
=
new
ArrayList
(
)
;
while
(
true
)
{
final
Object
o
=
readValue
(
object
)
;
if
(
o
!=
EMPTY_ARRAY
)
{
array
.
add
(
o
)
;
}
final
int
c
=
skipWhitespaceRead
(
)
;
if
(
c
==
'
'
)
{
break
;
}
else
if
(
c
!=
'
'
)
{
error
(
"Expected ',' or ']' inside array"
)
;
}
}
return
array
.
toArray
(
)
;
}


private Number readNumber(int c) throws IOException
    {
        final FastPushbackReader in = input;
        final StringBuilder number = numBuf;
        number.setLength(0);
        number.appendCodePoint(c);
        boolean isFloat = false;

        if (JsonReader.isLenient() && (c == '-' || c == 'N' || c == 'I') ) {
            // Handle negativity.
            final boolean isNeg = (c == '-');
            if (isNeg) {
                // Advance to next character.
                c = input.read();
            }

            // Case "-Infinity", "Infinity" or "NaN".
            if (c == 'I') {
                // [Out of RFC 4627] accept NaN/Infinity values
                readToken("infinity");
                return (isNeg) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
            } else if ('N' == c) {
                // [Out of RFC 4627] accept NaN/Infinity values
                readToken("nan");
                return Double.NaN;
            } else {
                // Case this is a number but not "-Infinity", like "-2". We let the normal code process.
                input.unread('-');
            }
        }

        while (true)
        {
            c = in.read();
            if ((c >= '0' && c <= '9') || c == '-' || c == '+')
            {
                number.appendCodePoint(c);
            }
            else if (c == '.' || c == 'e' || c == 'E')
            {
                number.appendCodePoint(c);
                isFloat = true;
            }
            else if (c == -1)
            {
                break;
            }
            else
            {
                in.unread(c);
                break;
            }
        }

        try
        {
            if (isFloat)
            {   // Floating point number needed
                return Double.parseDouble(number.toString());
            }
            else
            {
                return Long.parseLong(number.toString());
            }
        }
        catch (Exception e)
        {
            return (Number) error("Invalid number: " + number, e);
        }
    }

Read a JSON number

@param c int a character representing the first digit of the number that
was already read.
@return a Number (a Long or a Double) depending on whether the number is
a decimal number or integer.  This choice allows all smaller types (Float, int, short, byte)
to be represented as well.
@throws IOException for stream errors or parsing errors.