Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  MakeJNLP.java   Sprache: JAVA

 
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.nbbuild;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Delete;
import org.apache.tools.ant.taskdefs.ManifestException;
import org.apache.tools.ant.taskdefs.SignJar;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.zip.ZipOutputStream;
import org.xml.sax.SAXException;

/** Generates JNLP files for signed versions of the module JAR files.
 *
 * @author Jaroslav Tulach, Jesse Glick
 */

public class MakeJNLP extends Task {
    /** the files to work on */
    private ResourceCollection files;
    private SignJar signTask;

    private static final String MANIFEST = "META-INF/MANIFEST.MF";  //NOI18N
    private static final String UTF_8 = "UTF-8";    //NOI18N
    private static final String ATTR_CODEBASE = "Codebase"//NOI18N
    private static final String ATTR_PERMISSIONS = "Permissions";   //NOI18N
    private static final String ATTR_APPLICATION_NAME = "Application-Name"//NOI18N

    public FileSet createModules()
    throws BuildException {
        FileSet fs = new FileSet();
        fs.setProject(getProject());
        addConfigured(fs);
        return fs;
    }

    public void addConfigured(ResourceCollection rc) throws BuildException {
        if (files != nullthrow new BuildException("modules can be specified just once");
        files = rc;
    }

    private SignJar getSignTask() {
        if (signTask == null) {
            signTask = (SignJar)getProject().createTask("signjar");
        }
        return signTask;
    }
    
    private File targetFile;
    public void setDir(File t) {
        targetFile = t;
    }
    
    public void setAlias(String a) {
        getSignTask().setAlias(a);
    }
    
    public void setStorePass(String p) {
        getSignTask().setStorepass(p);
    }
    
    public void setKeystore(String k) {
        getSignTask().setKeystore(k);
    }

    public void setStoreType(String t) {
        getSignTask().setStoretype(t);
    }
    
    private String appName;

    public void setAppName(String appName) {
        this.appName = appName;
    }
    
    private final String manifestPermissions = "all-permissions";
    
    private final String manifestCodebase = "*";
    
    private String codebase = "$$codebase";
    public void setCodebase(String s) {
        this.codebase = s;
    }
    
    private boolean verify;
    public void setVerify(boolean v) {
        this.verify = v;
    }
    
    private String verifyExcludes;
    /** Comma separated list of allowed excluded names of files during verify
     * phase.
     */

    public void setVerifyExcludes(String s) {
        this.verifyExcludes = s;
    }

    private String permissions = "";
    /**
     * XML fragment pasted into the security part of the .jnlp file.
     * Should default to "<all-permissions/>"
     */

    public void setPermissions(String s) {
        permissions = s;
    }
    
    private FileSet indirectJars;
    /**
     * Other JARs which should be copied into the destination directory and referred to as resources,
     * even though they are not listed as Class-Path extensions of the module and would not normally
     * be in its effective classpath. The basedir of the fileset should be a cluster root; for each
     * such JAR, a file META-INF/clusterpath/$relpath will be inserted in the JAR, where $relpath is the
     * relative path within the cluster. This permits the JAR to be located at runtime in a flat classpath,
     * using ClassLoader.getResource.
     */

    public void addIndirectJars(FileSet fs) {
        indirectJars = fs;
    }

    private FileSet indirectFiles;
    /**
     * Other non-JAR files which should be made available to InstalledFileLocator.
     * The basedir of the fileset should be a cluster root; each
     * such file will be packed into a ZIP entry META-INF/files/$relpath
     * where the JAR will be available at runtime in a flat classpath,
     * using ClassLoader.getResource.
     */

    public void addIndirectFiles(FileSet fs) {
        indirectFiles = fs;
    }
    
    private boolean signJars = true;
    /**
     * Whether the final jars should be signed or not. Defaults to true
     * (if not supplied).
     */

    public void setSignJars(boolean s) {
        this.signJars = s;
    }
    
    private boolean processJarVersions = false;
    /**
     * Whether to add versions and sizes of jars into jnlp files. Defaults to false
     * (if not supplied).
     * @param b
     */

    public void setProcessJarVersions(boolean b) {
      this.processJarVersions = b;
    }
    
    private Map<String, String> jarVersions;
    /**
     * Explicit definition of jar file versions (for jars without versions specified
     * in manifest file)
     * @param jarVersions
     */

    public void setJarVersions(Map<String, String> jarVersions) {
      this.jarVersions = jarVersions;
    }
    
    private Set<String> nativeLibraries;
    public void setNativeLibraries(Set<String> libs) {
      this.nativeLibraries = libs;
    }

    private Set<File> jarDirectories;
    
    private String includelocales;
    public void setIncludelocales(String includelocales) {
        this.includelocales = includelocales;
    }
    
    /**
     * Signs or copies the given files according to the signJars variable value.
     */

    private void signOrCopy(File from, File to) {
        if (!from.exists() && from.getParentFile().getName().equals("locale")) {
            // skip missing locale files, probably the best fix for #103301
            log("Localization file " + from + " is referenced, but cannot be found. Skipping.", Project.MSG_WARN);
            return;
        }
        if (signJars) {
            getSignTask().setJar(from);
            if (to != null) {
                // #125970: might be .../modules/locale/something_ja.jar
                to.getParentFile().mkdirs();
            }
            getSignTask().setSignedjar(to);
            getSignTask().setDigestAlg("SHA1");
            getSignTask().execute();
        } else if (to != null) {
            Copy copy = (Copy)getProject().createTask("copy");
            copy.setFile(from);
            copy.setTofile(to);
            copy.execute();
        }        
        if (processJarVersions) {
          if (jarDirectories == null) {
            jarDirectories = new HashSet<>();
          }
          jarDirectories.add(new File(to.getParent()));
        }
    }
    
    @Override
    public void execute() throws BuildException {
        if (targetFile == nullthrow new BuildException("Output dir must be provided");
        if (files == nullthrow new BuildException("modules must be provided");
        try {
            generateFiles();
            if (processJarVersions && jarDirectories!=null && jarDirectories.size() > 0) {
              generateVersionXMLFiles();
            }
        } catch (IOException ex) {
            throw new BuildException(ex);
        }
    }
    
    private void generateFiles() throws IOException, BuildException {
        Set<String> declaredLocales = new HashSet<>();
        boolean useAllLocales = false;
        if(includelocales == null || "*".equals(includelocales)) {
            useAllLocales = true;
        } else if ("".equals(includelocales)) {
            useAllLocales = false;
        } else {
            StringTokenizer tokenizer = new StringTokenizer(includelocales, ",");
            while (tokenizer.hasMoreElements()) {
                declaredLocales.add(tokenizer.nextToken());
            }
        }
        Set<String> indirectFilePaths = new HashSet<>();
        File tmpFile = null;
        for (FileSet fs : new FileSet[] {indirectJars, indirectFiles}) {
            if (fs != null) {
                DirectoryScanner scan = fs.getDirectoryScanner(getProject());
                for (String f : scan.getIncludedFiles()) {
                    indirectFilePaths.add(f.replace(File.separatorChar, '/'));
                }
            }
        }

        for (Iterator<Resource> fileIt = files.iterator(); fileIt.hasNext();) {
            FileResource fr = (FileResource) fileIt.next();
            File jar = fr.getFile();

            if (!jar.canRead()) {
                throw new BuildException("Cannot read file: " + jar);
            }
            
            try (JarFile theJar = new JarFile(jar)) {
                String codenamebase = JarWithModuleAttributes.extractCodeName(theJar.getManifest().getMainAttributes());
                if (codenamebase == null) {
                    throw new BuildException("Not a NetBeans Module: " + jar);
                }
                if (
                        codenamebase.equals("org.objectweb.asm.all") &&
                        jar.getParentFile().getName().equals("core") &&
                        jar.getParentFile().getParentFile().getName().startsWith("platform")
                ) {
                    continue;
                }
                {
                    int slash = codenamebase.indexOf('/');
                    if (slash >= 0) {
                        codenamebase = codenamebase.substring(0, slash);
                    }
                }

                String dashcnb = codenamebase.replace('.''-');
                String title;
                String oneline;
                String shrt;
                String osDep = null;

                {
                    String bundle = theJar.getManifest().getMainAttributes().getValue("OpenIDE-Module-Localizing-Bundle");
                    Properties prop = new Properties();
                    if (bundle != null) {
                        ZipEntry en = theJar.getEntry(bundle);
                        if (en == null) {
                            throw new BuildException("Cannot find entry: " + bundle + " in file: " + jar);
                        }   try (InputStream is = theJar.getInputStream(en)) {
                            prop.load(is);
                        }
                    }
                    title = prop.getProperty("OpenIDE-Module-Name", codenamebase);
                    oneline = prop.getProperty("OpenIDE-Module-Short-Description", title);
                    shrt = prop.getProperty("OpenIDE-Module-Long-Description", oneline);
                }
                {
                    String osMan = theJar.getManifest().getMainAttributes().getValue("OpenIDE-Module-Requires");
                    if (osMan != null) {
                        if (osMan.indexOf("org.openide.modules.os.MacOSX") >= 0) { // NOI18N
                            osDep = "Mac OS X"// NOI18N
                        } else if (osMan.indexOf("org.openide.modules.os.Linux") >= 0) { // NOI18N
                            osDep = "Linux"// NOI18N
                        } else if (osMan.indexOf("org.openide.modules.os.Solaris") >= 0) { // NOI18N
                            osDep = "Solaris"// NOI18N
                        } else if (osMan.indexOf("org.openide.modules.os.Windows") >= 0) { // NOI18N
                            osDep = "Windows"// NOI18N
                        }
                    }
                }   Map<String,List<File>> localizedFiles = verifyExtensions(jar, theJar.getManifest(), dashcnb, codenamebase, verify, indirectFilePaths);
                new File(targetFile, dashcnb).mkdir();
                File signed = new File(new File(targetFile, dashcnb), jar.getName());
                File jnlp = new File(targetFile, dashcnb + ".jnlp");
                StringWriter writeJNLP = new StringWriter();
                writeJNLP.write("\n");
                writeJNLP.write("-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0//EN\" \"http://java.sun.com/dtd/JNLP-6.0.dtd\">\n");
                writeJNLP.write(""'>\n");
                writeJNLP.write(" \n");
                writeJNLP.write(" "</span> + XMLUtil.toElementContent(title) + <span style='color:blue'>"\n");
                writeJNLP.write(" NetBeans\n");
                writeJNLP.write(" " + XMLUtil.toElementContent(oneline) + "\n");
                writeJNLP.write(" " + XMLUtil.toElementContent(shrt) + "\n");
                writeJNLP.write(" \n");
                writeJNLP.write(permissions +"\n");
                if (osDep == null) {
                    writeJNLP.write(" \n");
                } else {
                    writeJNLP.write(" "'>\n");
                }   writeJNLP.write(constructJarHref(jar, dashcnb));
                processExtensions(jar, theJar.getManifest(), writeJNLP, dashcnb, codebase);
                processIndirectJars(writeJNLP, dashcnb);
                processIndirectFiles(writeJNLP, dashcnb);
                writeJNLP.write(" \n");
                if (useAllLocales || !declaredLocales.isEmpty()){
                    // write down locales
                    for (Map.Entry<String,List<File>> e : localizedFiles.entrySet()) {
                        String locale = e.getKey();
                        if (!declaredLocales.isEmpty() && !declaredLocales.contains(locale)) {
                            continue;
                        }
                        List<File> allFiles = e.getValue();
                        
                        writeJNLP.write(" "'>\n");
                        
                        for (File n : allFiles) {
                            log("generating locale " + locale + " for " + n, Project.MSG_VERBOSE);
                            String name = n.getName();
                            String clusterRootPrefix = jar.getParent() + File.separatorChar;
                            String absname = n.getAbsolutePath();
                            if (absname.startsWith(clusterRootPrefix)) {
                                name = absname.substring(clusterRootPrefix.length()).replace(File.separatorChar, '-');
                            }
                            File t = new File(new File(targetFile, dashcnb), name);
                            
                            File localeTmpFile = null;
                            if (n.exists() && isSigned(n) == null) {
                                try {
                                    localeTmpFile = extendLibraryManifest(getProject(), n, t, manifestCodebase, manifestPermissions, appName, jnlp);
                                } catch (IOException | ManifestException ex) {
                                    getProject().log(
                                            "Failed to extend libraries manifests: " + ex.getMessage(), //NOI18N
                                            Project.MSG_WARN);
                                }
                            } else {
                                getProject().log(
                                        String.format(
                                                "Not adding security attributes into locale library: %s the library is already signed.",
                                                safeRelativePath(getProject().getBaseDir(),t)),
                                        Project.MSG_WARN);
                            }
                            if (localeTmpFile != null) {
                                signOrCopy(localeTmpFile, t);
                                deleteTmpFile(localeTmpFile);
                            }
                            else {
                                signOrCopy(n, t);
                            }
                            writeJNLP.write(constructJarHref(n, dashcnb, name));
                        }
                        
                        writeJNLP.write(" \n");
                        
                    }
                }   writeJNLP.write(" \n");
                writeJNLP.write("\n");
                writeJNLP.close();
                FileWriter w = new FileWriter(jnlp);
                w.write(writeJNLP.toString());
                w.close();
                if (jar.exists() && isSigned(jar) == null) {
                    try {
                        tmpFile = extendLibraryManifest(getProject(), jar, signed, manifestCodebase, manifestPermissions, appName, jnlp);
                    } catch (IOException | ManifestException ex) {
                        getProject().log(
                                "Failed to extend libraries manifests: " + ex.getMessage(), //NOI18N
                                Project.MSG_WARN);
                    }
                } else {
                    getProject().log(
                            String.format(
                                    "Not adding security attributes into library: %s the library is already signed.",
                                    safeRelativePath(getProject().getBaseDir(),signed)),
                            Project.MSG_WARN);
                }   if (tmpFile != null) {
                    signOrCopy(tmpFile, signed);
                    deleteTmpFile(tmpFile);
                } else {
                    signOrCopy(jar, signed);
                }
            }
        }
        
    }
    
    private File extendLibraryManifest(
        final Project prj,
        final File sourceJar,
        final File signedJar,
        final String codebase,
        final String permissions,
        final String appName,
        final File jnlp) throws IOException, ManifestException {
        org.apache.tools.ant.taskdefs.Manifest manifest = null;
        Copy cp = new Copy();
        File tmpFile = new File(String.format("%s.tmp", signedJar.getAbsolutePath()));
        cp.setFile(sourceJar);
        cp.setTofile(tmpFile);
        cp.execute();
        boolean success = false;
        try {
            final Map<String,String> extendedAttrs = new HashMap<>();
            final org.apache.tools.zip.ZipFile zf = new org.apache.tools.zip.ZipFile(sourceJar);
            try {
                final org.apache.tools.zip.ZipEntry manifestEntry = zf.getEntry(MANIFEST);
                if (manifestEntry != null) {
                    final Reader in = new InputStreamReader(zf.getInputStream(manifestEntry), Charset.forName(UTF_8));    //NOI18N
                    try {
                        manifest = new org.apache.tools.ant.taskdefs.Manifest(in);
                    } finally {
                        in.close();
                    }
                } else {
                    manifest = new org.apache.tools.ant.taskdefs.Manifest();
                }
                final org.apache.tools.ant.taskdefs.Manifest.Section mainSection = manifest.getMainSection();
                String attr = mainSection.getAttributeValue(ATTR_CODEBASE);
                if (attr == null) {
                    mainSection.addAttributeAndCheck(new org.apache.tools.ant.taskdefs.Manifest.Attribute(
                        ATTR_CODEBASE,
                        codebase));
                    extendedAttrs.put(ATTR_CODEBASE, codebase);
                }
                attr = mainSection.getAttributeValue(ATTR_PERMISSIONS);
                if (attr == null) {
                    mainSection.addAttributeAndCheck(new org.apache.tools.ant.taskdefs.Manifest.Attribute(
                        ATTR_PERMISSIONS,
                        permissions));
                    extendedAttrs.put(ATTR_PERMISSIONS, permissions);
                }
                attr = mainSection.getAttributeValue(ATTR_APPLICATION_NAME);
                if (attr == null) {
                    mainSection.addAttributeAndCheck(new org.apache.tools.ant.taskdefs.Manifest.Attribute(
                        ATTR_APPLICATION_NAME,
                        appName));
                    extendedAttrs.put(ATTR_APPLICATION_NAME, appName);
                }
                if (!extendedAttrs.isEmpty()) {
                    final Enumeration<? extends org.apache.tools.zip.ZipEntry> zent = zf.getEntries();
                    final ZipOutputStream out = new ZipOutputStream(tmpFile);
                    try {
                        if (jnlp != null) {
                            org.apache.tools.zip.ZipEntry jnlpEntry = new org.apache.tools.zip.ZipEntry("JNLP-INF/" + jnlp.getName());
                            out.putNextEntry(jnlpEntry);
                            FileInputStream fis = new FileInputStream(jnlp.getAbsolutePath());
                            try {
                                copy(fis, out);
                            } finally {
                                fis.close();
                            }
                        }
                        while (zent.hasMoreElements()) {
                            final org.apache.tools.zip.ZipEntry entry = zent.nextElement();
                            final InputStream in = zf.getInputStream(entry);
                            try {
                                out.putNextEntry(entry);
                                if (MANIFEST.equals(entry.getName())) {
                                    final PrintWriter manifestOut = new PrintWriter(new OutputStreamWriter(out, Charset.forName(UTF_8)));
                                    manifest.write(manifestOut);
                                    manifestOut.flush();
                                } else {
                                    copy(in,out);
                                }
                            } finally {
                                in.close();
                            }
                        }
                    } finally {
                        out.close();
                    }
                    success = true;
                    final StringBuilder message = new StringBuilder("Updating library ").   //NOI18N
                        append(safeRelativePath(prj.getBaseDir(), tmpFile)).
                        append(" manifest");    //NOI18N
                    for (Map.Entry<String,String> e : extendedAttrs.entrySet()) {
                        message.append(String.format(" %s: %s,", e.getKey(), e.getValue()));
                    }
                    message.deleteCharAt(message.length()-1);
                    prj.log(message.toString(), Project.MSG_VERBOSE);
                }
            } finally {
                zf.close();
            }
        } finally {
            if (!success) {
                final Delete rm = new Delete();
                rm.setFile(tmpFile);
                rm.setQuiet(true);
                rm.execute();
                tmpFile = null;
            }
        }
        return tmpFile;
    }
    
    private static void deleteTmpFile(File tmpFile) {
        final Delete del = new Delete();
        del.setFile(tmpFile);
        del.execute();
    }

    private static void copy(final InputStream in, final OutputStream out) throws IOException {
        final byte[] BUFFER = new byte[4096];
        int len;
        for (;;) {
            len = in.read(BUFFER);
            if (len == -1) {
                return;
            }
            out.write(BUFFER, 0, len);
        }
    }

    private static String safeRelativePath(File from, File to) {
        try {
            return FileUtils.getRelativePath(from, to);
        } catch (Exception ex) {
            return to.getAbsolutePath();
        }
    }

    
    private Map<String,List<File>> verifyExtensions(File f, Manifest mf, String dashcnb, String codebasename, boolean verify, Set<String> indirectFilePaths) throws IOException, BuildException {
        Map<String,List<File>> localizedFiles = new HashMap<>();
        
        
        File clusterRoot = f.getParentFile();
        String moduleDirPrefix = "";
        File updateTracking;
        log("Verifying extensions for: " + codebasename + ", cluster root: " + clusterRoot + ", verify: " + verify, Project.MSG_DEBUG);
        for(;;) {
            updateTracking = new File(clusterRoot, "update_tracking");
            if (updateTracking.isDirectory()) {
                break;
            }
            moduleDirPrefix = clusterRoot.getName() + "/" + moduleDirPrefix;
            clusterRoot = clusterRoot.getParentFile();
            if (clusterRoot == null || !clusterRoot.exists()) {
                if (!verify) {
                    return localizedFiles;
                }
                
                throw new BuildException("Cannot find update_tracking directory for module " + f);
            }
        }

        File ut = new File(updateTracking, dashcnb + ".xml");
        if (!ut.exists()) {
            throw new BuildException("The file " + ut + " for module " + codebasename + " cannot be found");
        }

        Map<String,String> fileToOwningModule = new HashMap<>();
        try {
            ModuleSelector.readUpdateTracking(getProject(), ut.toString(), fileToOwningModule);
        } catch (IOException | ParserConfigurationException | SAXException ex) {
            throw new BuildException(ex);
        }
        
        log("project files: " + fileToOwningModule, Project.MSG_DEBUG);
        String name = relative(f, clusterRoot);
        log(" removing: " + name, Project.MSG_DEBUG);
        removeWithLocales(fileToOwningModule, name, clusterRoot, localizedFiles);
        name = "config/Modules/" + dashcnb + ".xml";
        log(" removing: " + name, Project.MSG_DEBUG);
        removeWithLocales(fileToOwningModule, name, clusterRoot, localizedFiles);
        name = "config/ModuleAutoDeps/" + dashcnb + ".xml";
        log(" removing: " + name, Project.MSG_DEBUG);
        removeWithLocales(fileToOwningModule, name, clusterRoot, localizedFiles);
        name = "update_tracking/" + dashcnb + ".xml";
        log(" removing: " + name, Project.MSG_DEBUG);
        removeWithLocales(fileToOwningModule, name, clusterRoot, localizedFiles);
        
        
        
        
        String path = mf.getMainAttributes().getValue("Class-Path");
        if (path != null) {
            StringTokenizer tok = new StringTokenizer(path, ", ");
            while(tok.hasMoreElements()) {
                String s = tok.nextToken();
                File e = new File(f.getParentFile(), s);
                String r = relative(e, clusterRoot);
                removeWithLocales(fileToOwningModule, r, clusterRoot, localizedFiles);
            }
        }

        fileToOwningModule.remove("ant/nblib/" + dashcnb + ".jar");

        fileToOwningModule.remove("VERSION.txt"); // cluster release information

        log(" removing: " + indirectFilePaths, Project.MSG_DEBUG);
        fileToOwningModule.keySet().removeAll(indirectFilePaths);
        
        if (verifyExcludes != null) {
            StringTokenizer tok = new StringTokenizer(verifyExcludes, ", ");
            while(tok.hasMoreElements()) {
                removeWithLocales(fileToOwningModule, tok.nextToken(), clusterRoot, localizedFiles);
            }
        }
            
        
        if (verify) {
            if (!fileToOwningModule.isEmpty()) {
                throw new BuildException(
                    "Cannot build JNLP for module " + f + " as these files are in " +
                    "module's NBM, but are not referenced from any path (see harness/README for properties you can define to fix):\n" + fileToOwningModule.keySet()
                );
            }
        }
        
        return localizedFiles;
    }
    
    private static void removeWithLocales(Map<String,String> removeFrom, String removeWhat, File clusterRoot, Map<String,List<File>> recordLocales) {
        if (removeFrom.remove(removeWhat) != null && removeWhat.endsWith(".jar")) {
            int basedir = removeWhat.lastIndexOf('/');
            String base = basedir == -1 ? "" : removeWhat.substring(0, basedir);
            String name = removeWhat.substring(basedir + 1, removeWhat.length() - 4);
            Pattern p = Pattern.compile(base + "/locale/" + name + "(|_[a-zA-Z0-9_]+)\\.jar");
            
            Iterator<String> it = removeFrom.keySet().iterator();
            while (it.hasNext()) {
                String s = it.next();
                Matcher m = p.matcher(s);
                if (m.matches()) {
                    String locale = m.group(1).substring(1);
                    
                    List<File> l = recordLocales.get(locale);
                    if (l == null) {
                        l = new ArrayList<>();
                        recordLocales.put(locale, l);
                    }
                    l.add(new File(clusterRoot, s.replace('/', File.separatorChar)));
                    it.remove();
                }
            }
        }
    }

    private void processExtensions(File f, Manifest mf, Writer fileWriter, String dashcnb, String codebase) throws IOException, BuildException {

        File nblibJar = new File(new File(new File(f.getParentFile().getParentFile(), "ant"), "nblib"), dashcnb + ".jar");
        if (nblibJar.isFile()) {
            File ext = new File(new File(targetFile, dashcnb), "ant-nblib-" + nblibJar.getName());
            fileWriter.write(constructJarHref(ext, dashcnb));
            signOrCopy(nblibJar, ext);
        }

        String path = mf.getMainAttributes().getValue("Class-Path");
        if (path == null) {
            return;
        }
        
        StringTokenizer tok = new StringTokenizer(path, ", ");
        while(tok.hasMoreElements()) {
            String s = URLDecoder.decode(tok.nextToken(), "UTF-8");
            
            if (s.contains("${java.home}")) {
                continue;
            }
            
            File e = new File(f.getParentFile(), s);
            if (!e.canRead()) {
                throw new BuildException("Cannot read extension " + e + " referenced from " + f);
            }
            String n = e.getName();
            if (n.endsWith(".jar")) {
                n = n.substring(0, n.length() - 4);
            }
            File ext = new File(new File(targetFile, dashcnb), s.replace("../""").replace('/''-'));

            if (e.exists() && isSigned(e) != null) {
                getProject().log(
                    String.format(
                        "Not adding security attributes into library: %s the library is already signed.",
                        safeRelativePath(getProject().getBaseDir(),ext)),
                    Project.MSG_WARN);
                Copy copy = (Copy)getProject().createTask("copy");
                copy.setFile(e);
                copy.setTofile(ext);
                copy.execute();
                
                String extJnlpName = dashcnb + '-' + ext.getName().replaceFirst("\\.jar$""") + ".jnlp";
                File jnlp = new File(targetFile, extJnlpName);

                try (FileWriter writeJNLP = new FileWriter(jnlp)) {
                    writeJNLP.write("\n");
                    writeJNLP.write("-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0//EN\" \"http://java.sun.com/dtd/JNLP-6.0.dtd\">\n");
                    writeJNLP.write(""'>\n");
                    writeJNLP.write(" \n");
                    writeJNLP.write(" "</span> + n + <span style='color:blue'>"\n");
                    writeJNLP.write(" NetBeans\n");
                    writeJNLP.write(" \n");
                    writeJNLP.write(permissions +"\n");
                    writeJNLP.write(" \n");
                    writeJNLP.write(constructJarHref(ext, dashcnb));
                    writeJNLP.write(" \n");
                    writeJNLP.write(" \n");
                    writeJNLP.write("\n");
                }
                
                fileWriter.write(" "\\.jar$""") + "' href='" + extJnlpName + "'/>\n");
            } else {
                File tmpFile = null;
                try {
                    tmpFile = extendLibraryManifest(getProject(), e, ext, manifestCodebase, manifestPermissions, appName, null);
                } catch (IOException | ManifestException ex) {
                    getProject().log(
                    "Failed to extend libraries manifests: " + ex.getMessage(), //NOI18N
                    Project.MSG_WARN);
                }
                if (tmpFile != null) {
                    signOrCopy(tmpFile, ext);
                    deleteTmpFile(tmpFile);
                } else {
                    signOrCopy(e, ext);
                }

                fileWriter.write(constructJarHref(ext, dashcnb));
            }
        }
    }

    private void processIndirectJars(Writer fileWriter, String dashcnb) throws IOException, BuildException {
        if (indirectJars == null) {
            return;
        }
        DirectoryScanner scan = indirectJars.getDirectoryScanner(getProject());
        for (String f : scan.getIncludedFiles()) {
            File jar = new File(scan.getBasedir(), f);
            String rel = f.replace(File.separatorChar, '/');
            String sig;
            try {
                sig = isSigned(jar);
            } catch (IOException x) {
                throw new BuildException("Cannot check signature on " + jar, x, getLocation());
            }
            // javaws will reject .zip files even with signatures.
            String rel2 = rel.endsWith(".jar") ? rel : rel.replaceFirst("(\\.zip)?$"".jar");
            File ext = new File(new File(targetFile, dashcnb), rel2.replace('/''-').replaceFirst("^modules-"""));
            Zip jartask = (Zip) getProject().createTask("jar");
            jartask.setDestFile(ext);
            ZipFileSet zfs = new ZipFileSet();
            zfs.setSrc(jar);
            if (sig != null) {
                // Need to cancel original signature since we are adding one entry to the JAR.
                zfs.setExcludes("META-INF/" + sig + ".*");
            }
            jartask.addZipfileset(zfs);
            zfs = new ZipFileSet();
            File blank = File.createTempFile("empty""");
            blank.deleteOnExit();
            zfs.setFile(blank);
            zfs.setFullpath("META-INF/clusterpath/" + rel);
            jartask.addZipfileset(zfs);
            jartask.execute();
            blank.delete();
            
            fileWriter.write(constructJarHref(ext, dashcnb));
            signOrCopy(ext, null);
        }
    }
    
    private void processIndirectFiles(Writer fileWriter, String dashcnb) throws IOException, BuildException {
        if (indirectFiles == null) {
            return;
        }
        DirectoryScanner scan = indirectFiles.getDirectoryScanner(getProject());
        Map<String,File> entries = new LinkedHashMap<>();
        for (String f : scan.getIncludedFiles()) {
            entries.put(f.replace(File.separatorChar, '/'), new File(scan.getBasedir(), f));
        }
        if (entries.isEmpty()) {
            return;
        }
        File ext = new File(new File(targetFile, dashcnb), "extra-files.jar");
        Zip jartask = (Zip) getProject().createTask("jar");
        jartask.setDestFile(ext);
        for (Map.Entry<String,File> entry : entries.entrySet()) {
            ZipFileSet zfs = new ZipFileSet();
            zfs.setFile(entry.getValue());
            zfs.setFullpath("META-INF/files/" + entry.getKey());
            jartask.addZipfileset(zfs);
        }
        jartask.execute();
        fileWriter.write(constructJarHref(ext, dashcnb));
        signOrCopy(ext, null);
    }

    private String relative(File file, File root) {
        String sfile = file.toString().replace(File.separatorChar, '/');
        String sroot = (root.toString() + File.separator).replace(File.separatorChar, '/');
        if (sfile.startsWith(sroot)) {
            try {
                String result = new URI(null, sfile.substring(sroot.length()), null).normalize().getPath();
                return result;
            } catch (URISyntaxException x) {
                throw new BuildException(x, getLocation()); // or just ignore?
            }
        }
        return sfile;
    }
    
    /** return alias if signed, or null if not */
    private static String isSigned(File f) throws IOException {
        try (JarFile jar = new JarFile(f)) {
            Enumeration<JarEntry> en = jar.entries();
            while (en.hasMoreElements()) {
                Matcher m = SF.matcher(en.nextElement().getName());
                if (m.matches()) {
                    return m.group(1);
                }
            }
            return null;
        }
    }
    private static final Pattern SF = Pattern.compile("META-INF/(.+)\\.SF");
    
    /**
     * returns version of jar file depending on manifest.mf or explicitly specified
     * @param jar
     * @return
     * @throws IOException
     */

    private String getJarVersion(JarFile jar) throws IOException {      
        String version = jar.getManifest().getMainAttributes().getValue("OpenIDE-Module-Specification-Version");
        if (version == null) {
          version = jar.getManifest().getMainAttributes().getValue("Specification-Version");
        }
        if (version == null && jarVersions != null) {
          version = jarVersions.get(jar.getName());
        }
        return version;
      }
    
    /**
     * Constructs jar or nativelib tag for jars
     * @param f
     * @param dashcnb
     * @return
     * @throws IOException
     */

    private String constructJarHref(File f, String dashcnb) throws IOException {
        return constructJarHref(f, dashcnb, f.getName());
    }

    /**
     * Constructs jar or nativelib tag for jars using custom name
     * @param f
     * @param dashcnb
     * @return
     * @throws IOException
     */

    private String constructJarHref(File f, String dashcnb, String name) throws IOException {
        String tag = "jar";
        if (nativeLibraries != null && nativeLibraries.contains(name)) {
            tag = "nativelib";
        }
        if (processJarVersions) {
            if (!f.exists()) {
                throw new BuildException("JAR file " + f + " does not exist, cannot extract required versioning info.");
            }
            JarFile extJar = new JarFile(f);
            String version = getJarVersion(extJar);
            if (version != null) {
                return " <" + tag + " href='" + dashcnb + '/' + name + "' version='" + version + "' size='" + f.length() + "'/>\n";
            }
        }
        return " <" + tag + " href='" + dashcnb + '/' + name + "'/>\n";
    }

    private void generateVersionXMLFiles() throws IOException {
        FileSet fs = new FileSet();
        fs.setIncludes("**/*.jar");
        for (File directory : jarDirectories) {
            fs.setDir(directory);
            DirectoryScanner scan = fs.getDirectoryScanner(getProject());
            StringWriter writeVersionXML = new StringWriter();
            writeVersionXML.append("1.0\" encoding=\"UTF-8\"?>\n");
            writeVersionXML.append("\n");
            for (String jarName : scan.getIncludedFiles()) {
                File jar = new File(scan.getBasedir(), jarName);
                JarFile jarFile = new JarFile(jar);
                String version = getJarVersion(jarFile);
                if (version != null) {
                    writeVersionXML.append(" \n \n ");
                    writeVersionXML.append(jar.getName());
                    writeVersionXML.append("\n ");
                    writeVersionXML.append(version);
                    writeVersionXML.append("\n \n ");
                    writeVersionXML.append(jar.getName());
                    writeVersionXML.append("\n \n");
                } else {
                    writeVersionXML.append(" \n");
                }
            }
            writeVersionXML.append("\n");
            writeVersionXML.close();

            File versionXML = new File(directory, "version.xml");
            FileWriter w = new FileWriter(versionXML);
            w.write(writeVersionXML.toString());
            w.close();
        }
    }

}

Messung V0.5
C=94 H=89 G=91

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge