101 } |
101 } |
102 EntryName en = new EntryName(path, version); |
102 EntryName en = new EntryName(path, version); |
103 basename = en.baseName; |
103 basename = en.baseName; |
104 entryname = en.entryName; |
104 entryname = en.entryName; |
105 } |
105 } |
|
106 |
|
107 @Override |
|
108 public boolean equals(Object o) { |
|
109 if (this == o) return true; |
|
110 if (!(o instanceof Entry)) return false; |
|
111 return this.file.equals(((Entry)o).file); |
|
112 } |
|
113 |
|
114 @Override |
|
115 public int hashCode() { |
|
116 return file.hashCode(); |
|
117 } |
106 } |
118 } |
107 |
119 |
108 class EntryName { |
120 class EntryName { |
109 final String baseName; |
121 final String baseName; |
110 final String entryName; |
122 final String entryName; |
122 // the old implementaton doesn't remove |
134 // the old implementaton doesn't remove |
123 // "./" if it was led by "/" (?) |
135 // "./" if it was led by "/" (?) |
124 if (name.startsWith("./")) { |
136 if (name.startsWith("./")) { |
125 name = name.substring(2); |
137 name = name.substring(2); |
126 } |
138 } |
127 this.baseName = name; |
139 baseName = name; |
128 this.entryName = (version > BASE_VERSION) |
140 entryName = (version > BASE_VERSION) |
129 ? VERSIONS_DIR + version + "/" + this.baseName |
141 ? VERSIONS_DIR + version + "/" + baseName |
130 : this.baseName; |
142 : baseName; |
131 } |
143 } |
132 } |
144 } |
133 |
145 |
134 // An entryName(path)->Entry map generated during "expand", it helps to |
146 // An entryName(path)->Entry map generated during "expand", it helps to |
135 // decide whether or not an existing entry in a jar file needs to be |
147 // decide whether or not an existing entry in a jar file needs to be |
136 // replaced, during the "update" operation. |
148 // replaced, during the "update" operation. |
137 Map<String, Entry> entryMap = new HashMap<>(); |
149 Map<String, Entry> entryMap = new HashMap<>(); |
138 |
150 |
139 // All entries need to be added/updated. |
151 // All entries need to be added/updated. |
140 Map<String, Entry> entries = new LinkedHashMap<>(); |
152 Set<Entry> entries = new LinkedHashSet<>(); |
141 |
153 |
142 // All packages. |
154 // All packages. |
143 Set<String> packages = new HashSet<>(); |
155 Set<String> packages = new HashSet<>(); |
144 // All actual entries added, or existing, in the jar file ( excl manifest |
156 // All actual entries added, or existing, in the jar file ( excl manifest |
145 // and module-info.class ). Populated during create or update. |
157 // and module-info.class ). Populated during create or update. |
853 if (f.isFile()) { |
865 if (f.isFile()) { |
854 if (entryName.endsWith(MODULE_INFO)) { |
866 if (entryName.endsWith(MODULE_INFO)) { |
855 moduleInfoPaths.put(entryName, f.toPath()); |
867 moduleInfoPaths.put(entryName, f.toPath()); |
856 if (isUpdate) |
868 if (isUpdate) |
857 entryMap.put(entryName, entry); |
869 entryMap.put(entryName, entry); |
858 } else if (!entries.containsKey(entryName)) { |
870 } else if (entries.add(entry)) { |
859 entries.put(entryName, entry); |
|
860 jarEntries.add(entryName); |
871 jarEntries.add(entryName); |
861 if (entry.basename.endsWith(".class") && !entryName.startsWith(VERSIONS_DIR)) |
872 if (entry.basename.endsWith(".class") && !entryName.startsWith(VERSIONS_DIR)) |
862 packages.add(toPackageName(entry.basename)); |
873 packages.add(toPackageName(entry.basename)); |
863 if (isUpdate) |
874 if (isUpdate) |
864 entryMap.put(entryName, entry); |
875 entryMap.put(entryName, entry); |
865 } |
876 } |
866 } else if (f.isDirectory()) { |
877 } else if (f.isDirectory()) { |
867 if (!entries.containsKey(entryName)) { |
878 if (entries.add(entry)) { |
868 entries.put(entryName, entry); |
|
869 if (isUpdate) { |
879 if (isUpdate) { |
870 entryMap.put(entryName, entry); |
880 entryMap.put(entryName, entry); |
871 } |
881 } |
872 expand(f, f.list(), isUpdate, moduleInfoPaths, version); |
882 expand(f, f.list(), isUpdate, moduleInfoPaths, version); |
873 } |
883 } |
1047 copy(zis, zos); |
1056 copy(zis, zos); |
1048 } else { // replace with the new files |
1057 } else { // replace with the new files |
1049 Entry ent = entryMap.get(name); |
1058 Entry ent = entryMap.get(name); |
1050 addFile(zos, ent); |
1059 addFile(zos, ent); |
1051 entryMap.remove(name); |
1060 entryMap.remove(name); |
1052 entries.remove(name); |
1061 entries.remove(ent); |
1053 } |
1062 } |
1054 |
1063 |
1055 jarEntries.add(name); |
1064 jarEntries.add(name); |
1056 if (name.endsWith(".class") && !(name.startsWith(VERSIONS_DIR))) |
1065 if (name.endsWith(".class") && !(name.startsWith(VERSIONS_DIR))) |
1057 packages.add(toPackageName(name)); |
1066 packages.add(toPackageName(name)); |
1058 } |
1067 } |
1059 } |
1068 } |
1060 |
1069 |
1061 // add the remaining new files |
1070 // add the remaining new files |
1062 for (String entryname : entries.keySet()) { |
1071 for (Entry entry : entries) { |
1063 addFile(zos, entries.get(entryname)); |
1072 addFile(zos, entry); |
1064 } |
1073 } |
1065 if (!foundManifest) { |
1074 if (!foundManifest) { |
1066 if (newManifest != null) { |
1075 if (newManifest != null) { |
1067 Manifest m = new Manifest(newManifest); |
1076 Manifest m = new Manifest(newManifest); |
1068 updateOk = !isAmbiguousMainClass(m); |
1077 updateOk = !isAmbiguousMainClass(m); |
1246 |
1255 |
1247 /** |
1256 /** |
1248 * Adds a new file entry to the ZIP output stream. |
1257 * Adds a new file entry to the ZIP output stream. |
1249 */ |
1258 */ |
1250 void addFile(ZipOutputStream zos, Entry entry) throws IOException { |
1259 void addFile(ZipOutputStream zos, Entry entry) throws IOException { |
|
1260 // skip the generation of directory entries for META-INF/versions/*/ |
|
1261 if (entry.basename.isEmpty()) return; |
|
1262 |
1251 File file = entry.file; |
1263 File file = entry.file; |
1252 String name = entry.entryname; |
1264 String name = entry.entryname; |
1253 boolean isDir = entry.isDir; |
1265 boolean isDir = entry.isDir; |
1254 |
1266 |
1255 if (name.equals("") || name.equals(".") || name.equals(zname)) { |
1267 if (name.equals("") || name.equals(".") || name.equals(zname)) { |