| /* |
| * 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.modules.extbrowser.plugins; |
| |
| import com.sun.jna.Library; |
| import com.sun.jna.Native; |
| import com.sun.jna.NativeMapped; |
| import com.sun.jna.Platform; |
| import com.sun.jna.PointerType; |
| import com.sun.jna.win32.W32APIOptions; |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.List; |
| import java.util.StringTokenizer; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipFile; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import org.json.simple.JSONObject; |
| import org.json.simple.JSONValue; |
| import org.json.simple.parser.ParseException; |
| |
| import org.openide.util.Utilities; |
| import org.w3c.dom.Document; |
| import org.xml.sax.SAXException; |
| |
| import static java.nio.charset.StandardCharsets.UTF_8; |
| |
| /** |
| * @author ads |
| * |
| */ |
| public final class Utils { |
| |
| private static final String APPDATA_CMD = "cmd /c echo %AppData%"; // NOI18N |
| |
| private Utils(){ |
| } |
| |
| public static String[] getUserPaths(String... paths) { |
| String[] result = new String[paths.length]; |
| String appRoot = getUserHome(); |
| |
| if (appRoot == null) { |
| return null; |
| } |
| for (int i = 0; i < paths.length; i++) { |
| result[i] = appRoot + paths[i]; |
| } |
| |
| return result; |
| } |
| |
| public static String unquote( String string ){ |
| if ( string.isEmpty() ){ |
| return string; |
| } |
| if ( string.charAt(0) == '"'){ |
| string = string.substring( 1 ); |
| } |
| if ( string.charAt(string.length() -1) == '"'){ |
| string = string.substring( 0, string.length() -1); |
| } |
| return string; |
| } |
| |
| public static JSONObject readFile( File file ){ |
| BufferedReader reader = null; |
| try { |
| reader = new BufferedReader(new InputStreamReader( |
| new FileInputStream(file), UTF_8)); |
| return (JSONObject)JSONValue.parseWithException(reader); |
| } catch (ParseException ex) { |
| Logger.getLogger( Utils.class.getCanonicalName()).log(Level.FINE, |
| "cannot parse JSON file "+file , ex ); |
| } catch ( IOException e ){ |
| Logger.getLogger( Utils.class.getCanonicalName()).log(Level.FINE, |
| null , e ); |
| } |
| finally { |
| if (reader != null) { |
| try { |
| reader.close(); |
| } |
| catch (IOException ex) { |
| Logger.getLogger(Utils.class. |
| getCanonicalName()).log(Level.FINE, null, ex); |
| } |
| } |
| } |
| return null; |
| } |
| |
| public static boolean compareChecksum( File zipFile, File checksumFile) { |
| if (zipFile == null) { |
| return true; |
| } |
| |
| String checkSumName = checksumFile.getName(); |
| |
| if (checksumFile.exists() && checksumFile.isFile()) { |
| ZipFile extensionZip = null; |
| try { |
| extensionZip = new ZipFile(zipFile); |
| ZipEntry entry = extensionZip.getEntry(checkSumName); |
| |
| if (entry != null) { |
| BufferedInputStream profileInput = new BufferedInputStream( |
| new FileInputStream(checksumFile)); |
| InputStream xpiInput = extensionZip.getInputStream(entry); |
| |
| try { |
| int red; |
| |
| do { |
| red = profileInput.read(); |
| if ( red != xpiInput.read() ){ |
| return false; |
| } |
| } |
| while (red>=0); |
| |
| return true; |
| } |
| finally { |
| profileInput.close(); |
| xpiInput.close(); |
| } |
| |
| } |
| } |
| catch (IOException ex) { |
| Logger.getLogger(Utils.class.getCanonicalName()). |
| log(Level.SEVERE, null , ex); |
| } |
| finally { |
| if (extensionZip != null) { |
| try { |
| extensionZip.close(); |
| } |
| catch (IOException ex) { |
| Logger.getLogger(Utils.class. |
| getCanonicalName()).log( |
| Level.SEVERE, |
| "Error closing zip file", ex); // NOI18N |
| } |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| public static void rmDir(File folder) { |
| if (!folder.exists()) { |
| return; |
| } |
| |
| File[] children = folder.listFiles(); |
| if (children != null) { |
| for (File child : children) { |
| rmDir(child); |
| } |
| } |
| folder.delete(); |
| } |
| |
| public static String readZip( File zipFile , String requiredName ){ |
| ZipFile zip = null; |
| try { |
| zip = new ZipFile(zipFile); |
| Enumeration<? extends ZipEntry> entries = zip.entries(); |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = entries.nextElement(); |
| String fileName = entry.getName(); |
| if ( fileName.equals(requiredName)){ |
| return readStream(zip.getInputStream(entry)); |
| } |
| } |
| } |
| catch( IOException ex ){ |
| Logger.getLogger(Utils.class.getCanonicalName()). |
| log(Level.INFO, null , ex); |
| } |
| finally { |
| try { |
| if ( zip!= null ){ |
| zip.close(); |
| } |
| } |
| catch( IOException ex ){ |
| Logger.getLogger(Utils.class.getCanonicalName()). |
| log(Level.INFO, null , ex); |
| } |
| } |
| return null; |
| } |
| |
| public static String readStream( InputStream inputStream ) |
| throws IOException |
| { |
| BufferedReader reader = new BufferedReader(new InputStreamReader( |
| inputStream ,UTF_8)); |
| return read( reader ); |
| } |
| |
| private static String read( BufferedReader reader ) throws IOException { |
| String line; |
| StringBuilder builder = new StringBuilder(); |
| do { |
| line = reader.readLine(); |
| if (line != null) { |
| builder.append(line); |
| } |
| } |
| while (line != null); |
| return builder.toString(); |
| } |
| |
| public static Document parseZipXml( File zipFile , String requiredName , |
| DocumentBuilder builder) throws SAXException |
| { |
| ZipFile zip = null; |
| try { |
| zip = new ZipFile(zipFile); |
| Enumeration<? extends ZipEntry> entries = zip.entries(); |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = entries.nextElement(); |
| String fileName = entry.getName(); |
| if ( fileName.equals(requiredName)){ |
| return builder.parse(zip.getInputStream(entry)); |
| } |
| } |
| } |
| catch( IOException ex ){ |
| Logger.getLogger(Utils.class.getCanonicalName()). |
| log(Level.INFO, null , ex); |
| } |
| finally { |
| try { |
| if ( zip!= null ){ |
| zip.close(); |
| } |
| } |
| catch( IOException ex ){ |
| Logger.getLogger(Utils.class.getCanonicalName()). |
| log(Level.INFO, null , ex); |
| } |
| } |
| return null; |
| } |
| |
| public static void extractFiles(File zipFile, File destDir) throws IOException { |
| ZipFile zip = new ZipFile(zipFile); |
| try { |
| destDir.mkdirs(); |
| Enumeration<? extends ZipEntry> entries = zip.entries(); |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = entries.nextElement(); |
| String fileName = entry.getName(); |
| |
| if (entry.isDirectory()) { |
| File newFolder = new File(destDir, fileName); |
| newFolder.mkdirs(); |
| } |
| else { |
| File file = new File(destDir, fileName); |
| file.getParentFile().mkdirs(); |
| if (file.exists() && file.isDirectory()) { |
| throw new IOException("Cannot write normal file " + |
| "to existing directory with the same path"); // NOI18N |
| } |
| |
| BufferedOutputStream output = new BufferedOutputStream( |
| new FileOutputStream(file)); |
| InputStream input = zip.getInputStream(entry); |
| |
| try { |
| final byte[] buffer = new byte[4096]; |
| int len; |
| while ((len = input.read(buffer)) >= 0) { |
| output.write(buffer, 0, len); |
| } |
| } |
| finally { |
| output.close(); |
| input.close(); |
| } |
| } |
| } |
| } |
| finally { |
| zip.close(); |
| } |
| } |
| |
| public static List<Integer> getVersionParts(String version) { |
| List<Integer> result = new ArrayList<>(); |
| |
| StringTokenizer tokens = new StringTokenizer(version, "."); |
| while (tokens.hasMoreTokens()) { |
| String nextToken = tokens.nextToken(); |
| try { |
| if (nextToken.contains("a")) { |
| int index = nextToken.indexOf("a"); |
| |
| String first = nextToken.substring(0, index); |
| String second = nextToken.substring(index + 1, |
| nextToken.length()); |
| |
| // version xxbyy is greater than any version xx-1 without a beta |
| // but less than version xx without a beta |
| result.add(Integer.parseInt(first) - 1); |
| result.add(-1); |
| result.add(Integer.parseInt(second)); |
| } else if (nextToken.contains("b")) { |
| int index = nextToken.indexOf("b"); |
| |
| String first = nextToken.substring(0, index); |
| String second = nextToken.substring(index + 1, |
| nextToken.length()); |
| |
| // version xxbyy is greater than any version xx-1 without a beta |
| // but less than version xx without a beta |
| result.add(Integer.parseInt(first) - 1); |
| result.add(Integer.parseInt(second)); |
| } else { |
| result.add(Integer.parseInt(nextToken)); |
| } |
| } catch (NumberFormatException ex) { |
| // skip values that are not numbers |
| } |
| } |
| |
| return result; |
| } |
| |
| private static String getUserHome() { |
| String userHome = System.getProperty("user.home"); // NOI18N |
| |
| if (!Utilities.isWindows()) { |
| return userHome; |
| } |
| else { |
| /*BufferedReader br = null; |
| try { |
| Process process = Runtime.getRuntime().exec(APPDATA_CMD); |
| process.waitFor(); |
| |
| InputStream input = process.getInputStream(); |
| br = new BufferedReader(new InputStreamReader(input)); |
| |
| while (br.ready()) { |
| String nextLine = br.readLine(); |
| |
| if (nextLine.trim().length() == 0) continue; |
| |
| File f = new File(nextLine.trim()); |
| if (f.exists() && f.isDirectory()) { |
| return f.getAbsolutePath(); |
| } |
| } |
| } |
| catch (Exception ex) { |
| Logger.getLogger(Utils.class.getCanonicalName()). |
| log(Level.INFO, "Unable to run process: " + APPDATA_CMD, ex ); // NOI18N |
| } |
| finally { |
| if (br != null) { |
| try { |
| br.close(); |
| } |
| catch (IOException ex) { |
| Logger.getLogger(Utils.class.getCanonicalName()). |
| log(Level.INFO, |
| "Unable close process input stream reader " , // NOI18N |
| ex ); |
| } |
| } |
| }*/ |
| |
| //return userHome + File.separator + "Application Data"; // NOI18N |
| return System.getenv("AppData"); // NOI18N |
| } |
| } |
| |
| // inspired by: http://stackoverflow.com/a/586917/1381125 |
| public static synchronized String getLOCALAPPDATAonWinXP() { |
| assert Platform.isWindows() : "cannot call getLOCALAPPDATAonWinXP on non-Windows OS"; // NOI18N |
| if (Platform.isWindows()) { |
| char[] pszPath = new char[Shell32.MAX_PATH]; |
| try { |
| if (Shell32_INSTANCE == null) { |
| Shell32_INSTANCE = Native.load("shell32", Shell32.class, W32APIOptions.UNICODE_OPTIONS); |
| } |
| int hResult = Shell32_INSTANCE.SHGetFolderPath(null, Shell32.CSIDL_LOCAL_APPDATA, |
| null, Shell32.SHGFP_TYPE_CURRENT, pszPath); |
| if (Shell32.S_OK == hResult) { |
| String path = new String(pszPath); |
| int len = path.indexOf('\0'); |
| path = path.substring(0, len); |
| return path; |
| } |
| } catch (Throwable t){ |
| // ignore |
| } |
| } |
| return null; |
| } |
| |
| private static Shell32 Shell32_INSTANCE; |
| |
| static class HANDLE extends PointerType implements NativeMapped { |
| } |
| |
| static class HWND extends HANDLE { |
| } |
| |
| static interface Shell32 extends Library { |
| |
| public static final int MAX_PATH = 260; |
| public static final int CSIDL_LOCAL_APPDATA = 0x001c; |
| public static final int SHGFP_TYPE_CURRENT = 0; |
| public static final int SHGFP_TYPE_DEFAULT = 1; |
| public static final int S_OK = 0; |
| |
| /** |
| * see http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx |
| * |
| * HRESULT SHGetFolderPath( HWND hwndOwner, int nFolder, HANDLE hToken, |
| * DWORD dwFlags, LPTSTR pszPath); |
| */ |
| public int SHGetFolderPath(HWND hwndOwner, int nFolder, HANDLE hToken, |
| int dwFlags, char[] pszPath); |
| |
| } |
| |
| |
| |
| } |