org.codehaus.groovy.grails.plugins.searchable.SearchableUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.groovy.grails.plugins.searchable.SearchableUtils.java

Source

/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.groovy.grails.plugins.searchable;

import org.codehaus.groovy.grails.commons.*;
import org.codehaus.groovy.grails.plugins.searchable.util.PatternUtils;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.util.Assert;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;
import java.util.regex.Pattern;
import java.io.File;
import java.io.IOException;

import grails.util.GrailsUtil;

/**
 * General purpose utilities for the Grails Searchable Plugin
 *
 * @author Maurice Nicholson
 */
public class SearchableUtils {
    private static Log log = LogFactory.getLog(SearchableUtils.class);
    private static final String PROJECT_META_FILE = "application.properties";
    public static final String SEARCHABLE_PROPERTY_NAME = "searchable";
    public static final String ONLY = "only";
    public static final String EXCEPT = "except";

    /**
     * Is the given class an emebedded property of another domain class?
     * @param grailsDomainClass the GrailsDomainClass to check as n embedded property
     * @param grailsDomainClasses all GrailsDomainClasses
     * @return true if the given class is an embedded property of another class
     */
    public static boolean isEmbeddedPropertyOfOtherDomainClass(GrailsDomainClass grailsDomainClass,
            Collection grailsDomainClasses) {
        for (Iterator iter = grailsDomainClasses.iterator(); iter.hasNext();) {
            GrailsDomainClass other = (GrailsDomainClass) iter.next();
            if (grailsDomainClass == other) {
                continue;
            }
            GrailsDomainClassProperty[] domainClassProperties = other.getProperties();
            for (int i = 0; i < domainClassProperties.length; i++) {
                GrailsDomainClass referencedDomainClass = domainClassProperties[i].getReferencedDomainClass();
                if (referencedDomainClass != null && referencedDomainClass == grailsDomainClass
                        && domainClassProperties[i].isEmbedded()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Get the given domain class's searchable property value, if any
     *
     * @param grailsDomainClass the Grails domain class
     * @return the searchable property value, or null
     */
    public static Object getSearchablePropertyValue(GrailsDomainClass grailsDomainClass) {
        return GrailsClassUtils.getStaticPropertyValue(grailsDomainClass.getClazz(), SEARCHABLE_PROPERTY_NAME);
    }

    /**
     * Gets the GrailsDomainClass artefacts from the aplication
     * @param application the Grails app
     * @return the Lit of domain classes
     */
    public static Collection getGrailsDomainClasses(GrailsApplication application) {
        Assert.notNull(application, "GrailsApplication cannot be null");
        Set domainClasses = new HashSet();
        for (int i = 0, max = application.getArtefacts(DomainClassArtefactHandler.TYPE).length; i < max; i++) {
            GrailsDomainClass grailsDomainClass = (GrailsDomainClass) application
                    .getArtefacts(DomainClassArtefactHandler.TYPE)[i];
            domainClasses.add(grailsDomainClass);
        }
        return domainClasses;
    }

    /**
     * Returns the class type of the searchable property
     * @param grailsDomainClass
     * @param propertyName
     * @param searchableGrailsDomainClasses
     * @return
     */
    public static Class getSearchablePropertyAssociatedClass(GrailsDomainClass grailsDomainClass,
            String propertyName, Collection searchableGrailsDomainClasses) {
        Assert.notNull(grailsDomainClass, "grailsDomainClass cannot be null");
        Assert.notNull(propertyName, "propertyName cannot be null");
        return getSearchablePropertyAssociatedClass(grailsDomainClass.getPropertyByName(propertyName),
                searchableGrailsDomainClasses);
    }

    /**
     * Returns the class type of the searchable property
     * @param property
     * @param searchableGrailsDomainClasses
     * @return
     */
    public static Class getSearchablePropertyAssociatedClass(GrailsDomainClassProperty property,
            Collection searchableGrailsDomainClasses) {
        Assert.notNull(property, "property cannot be null");
        Assert.notNull(property.getDomainClass(), "grailsDomainClass cannot be null");
        Class propertyType = property.getType();
        Collection classes = getClasses(searchableGrailsDomainClasses);
        if (classes.contains(propertyType)) {
            return propertyType;
        }
        propertyType = property.getDomainClass().getRelatedClassType(property.getName());
        if (propertyType != null && classes.contains(propertyType)) {
            return propertyType;
        }
        return null;
    }

    /**
     * Returns a collection of user classes for the given GrailsDomainClass instances
     * @param grailsDomainClasses a collection of GrailsDomainClass instances
     * @return a collection of user classes
     */
    public static Collection getClasses(Collection grailsDomainClasses) {
        Assert.notNull(grailsDomainClasses, "grailsDomainClasses cannot be null");
        Set classes = new HashSet();
        for (Iterator iter = grailsDomainClasses.iterator(); iter.hasNext();) {
            classes.add(((GrailsDomainClass) iter.next()).getClazz());
        }
        return classes;
    }

    /**
     * Should the named property be included in the mapping, according to the value of "searchable"?
     * @param propertyName
     * @param searchable
     * @return true if included
     */
    public static boolean isIncludedProperty(String propertyName, Object searchable) {
        if (searchable == null || (searchable instanceof Boolean && searchable.equals(Boolean.TRUE))) {
            return true;
        }
        if (!(searchable instanceof Map)) {
            return false;
        }
        Object only = ((Map) searchable).get(ONLY);
        if (only != null) {
            return isOrContains(propertyName, only);
        }
        return !isOrContains(propertyName, ((Map) searchable).get(EXCEPT));
    }

    private static boolean isOrContains(String thing, final Object value) {
        Collection values = null;
        if (value instanceof Collection) {
            values = (Collection) value;
        } else {
            values = new HashSet() {
                {
                    add(value);
                }
            };
        }
        for (Iterator iter = values.iterator(); iter.hasNext();) {
            String v = (String) iter.next();
            if (!PatternUtils.hasWildcards(v)) {
                if (v.equals(thing)) {
                    return true;
                }
            } else {
                Pattern pattern = PatternUtils.makePatternFromWilcardString(v);
                if (pattern.matcher(thing).matches()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Tries to resolve the Grails application name
     * @param grailsApplication the GrailsApplication instance which may be null
     * @return the app name or "app.name" if not found
     */
    public static String getAppName(GrailsApplication grailsApplication) {
        Map metadata = null;
        if (grailsApplication != null) {
            metadata = grailsApplication.getMetadata();
        }
        if (metadata == null) {
            metadata = loadMetadata();
        }
        if (metadata == null) {
            return "app.name";
        }
        return (String) metadata.get("app.name");
    }

    // adapted from DefaultGrailsApplication
    private static Map loadMetadata() {
        Resource r = new ClassPathResource(PROJECT_META_FILE);
        if (r.exists()) {
            return loadMetadata(r);
        }
        String basedir = System.getProperty("base.dir");
        if (basedir != null) {
            r = new FileSystemResource(new File(basedir, PROJECT_META_FILE));
            if (r.exists()) {
                return loadMetadata(r);
            }
        }
        return null;
    }

    private static Map loadMetadata(Resource resource) {
        try {
            Properties meta = new Properties();
            meta.load(resource.getInputStream());
            return meta;
        } catch (IOException e) {
            //            GrailsUtil.deepSanitize(e);
            log.warn("No application metadata file found at " + resource);
        }
        return null;
    }

}