Package play.deps

Source Code of play.deps.YamlParser$ModuleFilter

package play.deps;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ExcludeRule;
import org.apache.ivy.core.module.descriptor.MDArtifact;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ArtifactId;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.plugins.matcher.ExactOrRegexpPatternMatcher;
import org.apache.ivy.plugins.matcher.PatternMatcher;
import org.apache.ivy.plugins.parser.AbstractModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ParserSettings;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.yaml.snakeyaml.Yaml;

import play.Logger;
import play.Play;
import play.libs.IO;

public class YamlParser extends AbstractModuleDescriptorParser {

    static class Oops extends Exception {

        public Oops(String message) {
            super(message);
        }
    }

    public boolean accept(Resource rsrc) {
        return rsrc.exists() && rsrc.getName().endsWith(".yml");
    }
   
    public ModuleDescriptor parseDescriptor(ParserSettings ps, URL url, Resource rsrc, boolean bln) throws ParseException, IOException {
        try {
            InputStream srcStream =  rsrc.openStream();
            long lastModified = (rsrc != null?rsrc.getLastModified():0L);
           
            Yaml yaml = new Yaml();
            Object o = null;

            // Try to parse the yaml
            try {
                o = yaml.load(srcStream);
            } catch (Exception e) {
                throw new Oops(e.toString().replace("\n", "\n~ \t"));
            }

            // We expect a Map here
            if (!(o instanceof Map)) {
                throw new Oops("Unexpected format -> " + o);
            }

            Map data = (Map) o;
            ModuleRevisionId id = null;

            // Search for 'self' tag
            if (data.containsKey("self")) {
                if (data.get("self") instanceof String) {
                    Matcher m = Pattern.compile("([^\\s]+)\\s*[-][>]\\s*([^\\s]+)\\s+([^\\s]+).*").matcher(data.get("self").toString());
                    if (m.matches()) {
                        String org = m.group(1);
                        String name = m.group(2);
                        String rev = m.group(3).replace("$version", System.getProperty("play.version"));
                        id = ModuleRevisionId.newInstance(org, name, rev);
                    } else {
                        throw new Oops("Unknown self format -> " + data.get("self"));
                    }
                } else {
                    throw new Oops("Unknown self format -> " + data.get("self"));
                }
            } else {
                String org = "play-application";
                String name = new File(System.getProperty("application.path")).getName();
                String rev = "1.0";
                id = ModuleRevisionId.newInstance(org, name, rev);
            }

            DefaultModuleDescriptor descriptor = new DefaultModuleDescriptor(id, "release", null, true) {
                @Override
                public ModuleDescriptorParser getParser() {
                    return new YamlParser();
                }
            };
            descriptor.addConfiguration(new Configuration("default"));
            descriptor.addArtifact("default", new MDArtifact(descriptor, id.getName(), "jar", "zip"));
            descriptor.setLastModified(lastModified);

            boolean transitiveDependencies = get(data, "transitiveDependencies", boolean.class, true);
           
            List<String> confs = new ArrayList<String>();
            if (data.containsKey("configurations")) {
                if (data.get("configurations") instanceof List) {
                    boolean allExcludes = true;
                    List configurations = (List) data.get("configurations");
                    for (Object conf : configurations) {
                        String confName;
                        Map options;
                       
                        if (conf instanceof String) {
                            confName = ((String) conf).trim();
                            options = new HashMap();
                        } else if (conf instanceof Map) {
                            confName = ((Map) conf).keySet().iterator().next().toString().trim();
                            options = (Map) ((Map) conf).values().iterator().next();
                        } else {
                            throw new Oops("Unknown configuration format -> " + conf);
                        }
                        boolean exclude = options.containsKey("exclude") && options.get("exclude") instanceof Boolean ? (Boolean) options.get("exclude") : false;
                        allExcludes &=  exclude;
                        confs.add((exclude ? "!" : "") + confName);
                    }
                   
                    if (allExcludes) {
                        confs.add(0, "*");
                    }
                } else {
                    throw new Oops("Unknown \"configurations\" format -> " + data.get("self"));
                }
            } else {
                confs.add("*");
            }
           
            if (data.containsKey("require")) {
                if (data.get("require") instanceof List) {

                    List dependencies = (List) data.get("require");
                    for (Object dep : dependencies) {

                        String depName;
                        Map options;

                        if (dep instanceof String) {
                            depName = ((String) dep).trim();
                            options = new HashMap();
                        } else if (dep instanceof Map) {
                            depName = ((Map) dep).keySet().iterator().next().toString().trim();
                            options = (Map) ((Map) dep).values().iterator().next();
                        } else {
                            throw new Oops("Unknown dependency format -> " + dep);
                        }

                        // Hack
                        depName = depName.replace("$version", System.getProperty("play.version"));
                        if(depName.matches("play\\s+->\\s+play") || depName.equals("play")) {
                            depName = "play -> play " + System.getProperty("play.version");
                        }
                        if(depName.matches("play\\s+->\\s+crud") || depName.equals("crud")) {
                            depName = "play -> crud " + System.getProperty("play.version");
                        }
                        if(depName.matches("play\\s+->\\s+secure") || depName.equals("secure")) {
                            depName = "play -> secure " + System.getProperty("play.version");
                        }

                        // Pattern compile to match [organisation name] - > [artifact] [revision] [classifier]
                        Matcher m = Pattern.compile("([^\\s]+)\\s*[-][>]\\s*([^\\s]+)\\s+([^\\s]+)(\\s+[^\\s]+)?.*").matcher(depName);
                        if (!m.matches()) {
                         // Pattern compile to match [artifact] [revision] [classifier]
                            m = Pattern.compile("(([^\\s]+))\\s+([^\\s]+)(\\s+[^\\s]+)?.*").matcher(depName);
                            if (!m.matches()) {
                                throw new Oops("Unknown dependency format -> " + depName);
                            } else if( m.groupCount() >= 3 && m.group(3).trim().equals("->")){
                                throw new Oops("Missing revision in dependency format (use \"latest.integration\" to  matches all versions) -> " + depName);
                            }
                        }
                        HashMap extraAttributesMap = null;
                  if(m.groupCount() == 4 &&  m.group(4) != null && !m.group(4).trim().isEmpty()){
                      // dependency has a classifier
                      extraAttributesMap = new HashMap();
                      extraAttributesMap.put("classifier", m.group(4).trim());
                  }

                        ModuleRevisionId depId = ModuleRevisionId.newInstance(m.group(1), m.group(2), m.group(3), extraAttributesMap);

                        boolean transitive = options.containsKey("transitive") && options.get("transitive") instanceof Boolean ? (Boolean) options.get("transitive") : transitiveDependencies;
                        boolean force = options.containsKey("force") && options.get("force") instanceof Boolean ? (Boolean) options.get("force") : false;
                        boolean changing = options.containsKey("changing") && options.get("changing") instanceof Boolean ? (Boolean) options.get("changing") : false;

                        DefaultDependencyDescriptor depDescriptor = new DefaultDependencyDescriptor(descriptor, depId, force, changing, transitive);
                        for (String conf : confs) {
                            depDescriptor.addDependencyConfiguration("default", conf);
                        }

                        // Exclude transitive dependencies
                        if (options.containsKey("exclude") && options.get("exclude") instanceof List) {
                            List exclude = (List) options.get("exclude");
                            for (Object ex : exclude) {
                                String exName = ex.toString().trim();
                                m = Pattern.compile("([^\\s]+)\\s*[-][>]\\s*([^\\s]+).*").matcher(exName);
                                if (!m.matches()) {
                                    m = Pattern.compile("([^\\s]+)").matcher(exName);
                                    if (!m.matches()) {
                                        throw new Oops("Unknown exclude format -> " + exName);
                                    }
                                }
                                String org = m.group(1);
                                String module = "*";
                                if (m.groupCount() > 1) {
                                    module = m.group(2);
                                }

                                ArtifactId aid = new ArtifactId(new ModuleId(org, module), "*", "*", "*");
                                PatternMatcher matcher = new ExactOrRegexpPatternMatcher();
                                ExcludeRule excludeRule = new DefaultExcludeRule(aid, matcher, new HashMap());
                                depDescriptor.addExcludeRule("default", excludeRule);
                            }
                        }

                        // Ids
                        boolean useIt = true;
                        String currentId = System.getProperty("play.id");
                        if (currentId == null || currentId.trim().equals("")) {
                            currentId = "unset";
                        }
                        if (options.containsKey("id")) {
                            if (options.get("id") instanceof String) {
                                useIt = options.get("id").toString().equals(currentId);
                            } else if (options.get("id") instanceof List) {
                                useIt = ((List) options.get("id")).contains(currentId);
                            }
                        }

                        if (useIt) {
                            // Add it!
                            descriptor.addDependency(depDescriptor);
                        }

                    }

                } else {
                    throw new Oops("require list not found -> " + o);
                }
            }

            return descriptor;

        } catch (Oops e) {
            System.out.println("~ Oops, malformed dependencies.yml descriptor:");
            System.out.println("~");
            System.out.println("~ \t" + e.getMessage());
            System.out.println("~");
            throw new ParseException("Malformed dependencies.yml descriptor", 0);
        }
    }

    public void toIvyFile(InputStream in, Resource rsrc, File file, ModuleDescriptor md) throws ParseException, IOException {
        ((DefaultModuleDescriptor)md).toIvyFile(file);
    }

    @SuppressWarnings("unchecked")
    <T> T get(Map data, String key, Class<T> type) {
        if (data.containsKey(key)) {
            Object o = data.get(key);
            if (type.isAssignableFrom(o.getClass())) {
                if(o instanceof String) {
                    o = o.toString().replace("${play.path}", System.getProperty("play.path"));
                    o = o.toString().replace("${application.path}", System.getProperty("application.path"));
                }
                return (T) o;
            }
        }
        return null;
    }

    <T> T get(Map data, String key, Class<T> type, T defaultValue) {
        T o = get(data, key, type);
        if (o == null) {
            return defaultValue;
        }
        return o;
    }

    public static Set<String> getOrderedModuleList(File file) throws FileNotFoundException, ParseException, IOException {
        Set<String> modules = new LinkedHashSet<String>();
        System.setProperty("application.path", Play.applicationPath.getAbsolutePath());
        return getOrderedModuleList(modules, file);
    }
       
   private static Set<String> getOrderedModuleList(Set<String> modules, File file) throws FileNotFoundException, ParseException, IOException {
        if (file == null || !file.exists()) {
            throw new FileNotFoundException("There was a problem to find the file");
        }

        YamlParser parser = new YamlParser();

        ModuleDescriptor md = parser.parseDescriptor(null, null, new URLResource(file.toURI().toURL()), true);

        DependencyDescriptor[] rules = md.getDependencies();
        File localModules = Play.getFile("modules");
        for (DependencyDescriptor dep : rules) {
            ModuleRevisionId rev = dep.getDependencyRevisionId();      
            String moduleName = filterModuleName(rev);
           
            // Check if the module was already load to avoid circular parsing
            if (moduleName != null && !modules.contains(moduleName)) {
                // Add the given module
                modules.add(moduleName);
               
                // Need to load module dependencies of this given module
                File module = new File(localModules, moduleName);
                if(module != null && module.isDirectory()) { 
                    File ivyModule = new File(module, "conf/dependencies.yml");
                    if(ivyModule != null && ivyModule.exists()) {
                        getOrderedModuleList(modules, ivyModule);
                    }   
                } else {
                    File modulePath = new File(IO.readContentAsString(module).trim());
                    if (modulePath.exists() && modulePath.isDirectory()) {
                        File ivyModule = new File(modulePath, "conf/dependencies.yml");
                        if(ivyModule != null && ivyModule.exists()) {
                            getOrderedModuleList(modules, ivyModule);
                        }
                    }
                }
            } else if(moduleName == null && rev.getRevision().equals("->")){
                Logger.error("Revision is required, module [%s -> %s] will not be loaded.", rev.getName(), rev.getExtraAttribute("classifier"));
            }
        }
        return modules;
    }
   
     
    private static String filterModuleName(ModuleRevisionId rev) {
        if (rev != null && !"play".equals(rev.getName())) {
            File moduleDir = new File(Play.applicationPath, "modules");
            if(moduleDir != null && moduleDir.isDirectory()){
                // create new filename filter to check if it is a module (lib will
                // be skipped)
                File[] filterFiles = moduleDir.listFiles(new ModuleFilter(rev));
                if (filterFiles != null && filterFiles.length > 0) {
                    return filterFiles[0].getName();
               }
            }
        }
        return null;
    }
   
    private static class ModuleFilter implements FilenameFilter {

        private ModuleRevisionId moduleRevision;

        public ModuleFilter(ModuleRevisionId moduleRevision) {
            this.moduleRevision = moduleRevision;
        }
        @Override
        public boolean accept(File dir, String name) {
            // Accept module with the same name or with a version number
            if (name != null && moduleRevision != null &&
                    (name.equals(moduleRevision.getName())
                    || name.equals(moduleRevision.getName() + "-" + moduleRevision.getRevision())
                    || name.startsWith(moduleRevision.getName() + "-"))) {
                return true;
            }
            return false;
        }
    }

}
TOP

Related Classes of play.deps.YamlParser$ModuleFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.