CleanProperties.java revision 3022:5ba1a29a0eb0
1105197Ssam/*
2105197Ssam * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
3105197Ssam * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4139823Simp *
5105197Ssam * This code is free software; you can redistribute it and/or modify it
6105197Ssam * under the terms of the GNU General Public License version 2 only, as
7105197Ssam * published by the Free Software Foundation.  Oracle designates this
8105197Ssam * particular file as subject to the "Classpath" exception as provided
9105197Ssam * by Oracle in the LICENSE file that accompanied this code.
10105197Ssam *
11105197Ssam * This code is distributed in the hope that it will be useful, but WITHOUT
12105197Ssam * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13105197Ssam * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14105197Ssam * version 2 for more details (a copy is included in the LICENSE file that
15105197Ssam * accompanied this code).
16105197Ssam *
17105197Ssam * You should have received a copy of the GNU General Public License version
18105197Ssam * 2 along with this work; if not, write to the Free Software Foundation,
19105197Ssam * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20105197Ssam *
21105197Ssam * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22105197Ssam * or visit www.oracle.com if you need additional information or have any
23105197Ssam * questions.
24105197Ssam */
25105197Ssam
26105197Ssampackage com.sun.tools.sjavac;
27105197Ssam
28105197Ssamimport java.io.BufferedWriter;
29105197Ssamimport java.io.File;
30105197Ssamimport java.io.FileInputStream;
31105197Ssamimport java.io.FileOutputStream;
32105197Ssamimport java.io.IOException;
33105197Ssamimport java.io.OutputStreamWriter;
34105197Ssamimport java.io.Writer;
35105197Ssamimport java.net.URI;
36105197Ssamimport java.util.ArrayList;
37105197Ssamimport java.util.Collections;
38105197Ssamimport java.util.HashSet;
39105197Ssamimport java.util.List;
40105197Ssamimport java.util.Map;
41105197Ssamimport java.util.Properties;
42105197Ssamimport java.util.Set;
43105197Ssam
44105197Ssamimport com.sun.tools.sjavac.comp.CompilationService;
45105197Ssamimport com.sun.tools.sjavac.options.Options;
46105197Ssamimport com.sun.tools.sjavac.pubapi.PubApi;
47105197Ssam
48105197Ssam/**
49105197Ssam * The clean properties transform should not be necessary.
50105197Ssam * Eventually we will cleanup the property file sources in the OpenJDK instead.
51105197Ssam *
52105197Ssam *  <p><b>This is NOT part of any supported API.
53105197Ssam *  If you write code that depends on this, you do so at your own risk.
54105197Ssam *  This code and its internal interfaces are subject to change or
55105197Ssam *  deletion without notice.</b>
56105197Ssam */
57105197Ssampublic class CleanProperties implements Transformer {
58105197Ssam    public void setExtra(String e) {
59105197Ssam        // Any extra information is ignored for clean properties.
60105197Ssam    }
61105197Ssam
62105197Ssam    public void setExtra(Options a) {
63105197Ssam        // Any extra information is ignored for clean properties.
64105197Ssam    }
65105197Ssam
66105197Ssam    public boolean transform(CompilationService sjavac,
67105197Ssam                             Map<String,Set<URI>> pkgSrcs,
68105197Ssam                             Set<URI>             visibleSrcs,
69157123Sgnn                             Map<URI,Set<String>> visibleClasses,
70157123Sgnn                             Map<String,Set<String>> oldPackageDependencies,
71105197Ssam                             URI destRoot,
72105197Ssam                             Map<String,Set<URI>>    packageArtifacts,
73105197Ssam                             Map<String, Map<String, Set<String>>> packageDependencies,
74105197Ssam                             Map<String, Map<String, Set<String>>> packageCpDependencies,
75                             Map<String, PubApi> packagePublicApis,
76                             Map<String, PubApi> dependencyPublicApis,
77                             int debugLevel,
78                             boolean incremental,
79                             int numCores,
80                             Writer out,
81                             Writer err) {
82        boolean rc = true;
83        for (String pkgName : pkgSrcs.keySet()) {
84            String pkgNameF = pkgName.replace('.',File.separatorChar);
85            for (URI u : pkgSrcs.get(pkgName)) {
86                File src = new File(u);
87                boolean r = clean(pkgName, pkgNameF, src, new File(destRoot), debugLevel,
88                                  packageArtifacts);
89                if (r == false) {
90                    rc = false;
91                }
92            }
93        }
94        return rc;
95    }
96
97    boolean clean(String pkgName,
98                  String pkgNameF,
99                  File src,
100                  File destRoot,
101                  int debugLevel,
102                  Map<String,Set<URI>> packageArtifacts) {
103        // Load the properties file.
104        Properties p = new Properties();
105        try {
106            p.load(new FileInputStream(src));
107        } catch (IOException e) {
108            Log.error("Error reading file "+src.getPath());
109            return false;
110        }
111
112        // Sort the properties in increasing key order.
113        List<String> sortedKeys = new ArrayList<>();
114        for (Object key : p.keySet()) {
115            sortedKeys.add((String)key);
116        }
117        Collections.sort(sortedKeys);
118
119        // Collect the properties into a string buffer.
120        StringBuilder data = new StringBuilder();
121        for (String key : sortedKeys) {
122            data.append(CompileProperties.escape(key))
123                .append(":")
124                .append(CompileProperties.escape((String) p.get(key)))
125                .append("\n");
126        }
127
128        String destFilename = destRoot.getPath()+File.separator+pkgNameF+File.separator+src.getName();
129        File dest = new File(destFilename);
130
131        // Make sure the dest directories exist.
132        if (!dest.getParentFile().isDirectory()) {
133            if (!dest.getParentFile().mkdirs()) {
134                Log.error("Could not create the directory "+dest.getParentFile().getPath());
135                return false;
136            }
137        }
138
139        Set<URI> as = packageArtifacts.get(pkgName);
140        if (as == null) {
141            as = new HashSet<>();
142            packageArtifacts.put(pkgName, as);
143        }
144        as.add(dest.toURI());
145
146        if (dest.exists() && dest.lastModified() > src.lastModified()) {
147            // A cleaned property file exists, and its timestamp is newer than the source.
148            // Assume that we do not need to clean!
149            // Thus we are done.
150            return true;
151        }
152
153        Log.info("Cleaning property file "+pkgNameF+File.separator+src.getName());
154        try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest)))) {
155            writer.write(data.toString());
156        } catch ( IOException e ) {
157            Log.error("Could not write file "+dest.getPath());
158            return false;
159        }
160        return true;
161    }
162}
163