# HG changeset patch # User Vladimir Kvashin # Date 1479820256 -10800 # Branch release82 # Node ID 45e7429e970a1d6119bf174d5f0d93dd73d6646a # Parent 13ee6f16f094717f3fa9f450d6d9ca01a46e8c86 Prototype for fixing #247673 - "New Project" wizard works too slowly in FullRemote case diff -r 13ee6f16f094 -r 45e7429e970a cnd.makeproject/src/org/netbeans/modules/cnd/makeproject/api/wizards/MakeSampleProjectGenerator.java --- a/cnd.makeproject/src/org/netbeans/modules/cnd/makeproject/api/wizards/MakeSampleProjectGenerator.java Wed Nov 16 13:27:01 2016 +0300 +++ b/cnd.makeproject/src/org/netbeans/modules/cnd/makeproject/api/wizards/MakeSampleProjectGenerator.java Tue Nov 22 16:10:56 2016 +0300 @@ -43,10 +43,13 @@ */ package org.netbeans.modules.cnd.makeproject.api.wizards; +import com.sun.javafx.util.Utils; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -85,8 +88,10 @@ import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory; import org.netbeans.modules.nativeexecution.api.util.ProcessUtils; import org.netbeans.modules.remote.spi.FileSystemProvider; +import org.netbeans.modules.remote.spi.WarmapHintProvider; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileSystem; import org.openide.filesystems.FileUtil; import org.openide.filesystems.URLMapper; import org.openide.util.Lookup; @@ -520,8 +525,47 @@ } } - private static void unzip(InputStream source, FileObject targetFolder) throws IOException { + private static void unzip(InputStream source, FileObject targetFolder) throws IOException { //installation + final ExecutionEnvironment env = FileSystemProvider.getExecutionEnvironment(targetFolder); + if (env.isRemote()) { + final FileSystem fs = targetFolder.getFileSystem(); + final FileObject zipFO = fs.createTempFile(targetFolder, "__tmp", ".zip", false); //NOI18N + final OutputStream os = zipFO.getOutputStream(); + File tmpZipFile = null; + try { + tmpZipFile = File.createTempFile("sample", ".zip"); + try (FileOutputStream fos = new FileOutputStream(tmpZipFile)) { + FileUtil.copy(source, fos); + } + source = new FileInputStream(tmpZipFile); + FileUtil.copy(source, os); + os.close(); +// StringBuilder script = new StringBuilder(); +// script.append("\'").append("unzip -q ").append(zipFO.getNameExt()).append(" && rm ").append(zipFO.getPath()); //NOI18N +//// if (Utils.isWindows() || Boolean.getBoolean("remote.test.dos2unix")) { //NOI18N +//// script.append(" && (which dos2unix > /dev/null; if [ $? = 0 ]; then find . -name \"*[Mm]akefile*\" -exec dos2unix {} \\; ; else echo \"no_dos2unix\"; fi)"); //NOI18N +//// } +// script.append("\'"); //NOI18N +// ProcessUtils.ExitStatus rc = ProcessUtils.executeInDir(targetFolder.getPath(), env, "sh", "-x", "-c", script.toString()); //NOI18N + ProcessUtils.ExitStatus rc = ProcessUtils.executeInDir(targetFolder.getPath(), env, "unzip", "-q", zipFO.getNameExt()); //NOI18N + if (!rc.isOK()) { + throw new IOException(rc.getErrorString()); + } + WarmapHintProvider.setWarmupZip(targetFolder, tmpZipFile); + List out = rc.getOutputLines(); + if (out != null && !out.isEmpty() && out.get(0).startsWith("no_dos2unix")) { //NOI18N + // There is no dos2unix on the machine: + // need to update makefiles one by one + } + } finally { +// if (tmpZipFile != null) { +// tmpZipFile.delete(); +// } + targetFolder.refresh(); + } + return; + } ZipInputStream zip = new ZipInputStream(source); try { ZipEntry ent; diff -r 13ee6f16f094 -r 45e7429e970a dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/RemoteDirectory.java --- a/dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/RemoteDirectory.java Wed Nov 16 13:27:01 2016 +0300 +++ b/dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/RemoteDirectory.java Tue Nov 22 16:10:56 2016 +0300 @@ -44,6 +44,7 @@ import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -80,6 +81,7 @@ import org.netbeans.modules.remote.impl.fileoperations.spi.FilesystemInterceptorProvider; import org.netbeans.modules.remote.impl.fileoperations.spi.FilesystemInterceptorProvider.FilesystemInterceptor; import org.netbeans.modules.remote.spi.FileSystemProvider; +import org.netbeans.modules.remote.spi.WarmapHintProvider; import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileEvent; import org.openide.filesystems.FileLock; @@ -89,6 +91,9 @@ import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.Parameters; +import static java.nio.file.StandardCopyOption.*; +import java.util.zip.ZipInputStream; +import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory; /** * @@ -1466,8 +1471,27 @@ } } + void setWarmupZip(File zip) { + getCache().mkdirs(); + try { + RemoteFileSystemUtils.unpackZipFile(zip, getCache()); + } catch (IOException ex) { + RemoteLogger.fine(ex); + } + } + private boolean ensureChildSyncFromZip(RemotePlainFile child) { File file = new File(getCache(), RemoteFileSystem.CACHE_ZIP_FILE_NAME); + if (!file.exists()) { + File andRemoveWarmupZip = WarmapHintProvider.getAndRemoveWarmupZip(this.getOwnerFileObject()); + if (andRemoveWarmupZip != null && andRemoveWarmupZip.exists()) { + try { + Files.move(andRemoveWarmupZip.toPath(), file.toPath(), REPLACE_EXISTING); + } catch (IOException ex) { + ex.printStackTrace(System.err); + } + } + } if (file.exists()) { ZipFile zipFile = null; InputStream is = null; diff -r 13ee6f16f094 -r 45e7429e970a dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/RemoteFileSystemUtils.java --- a/dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/RemoteFileSystemUtils.java Wed Nov 16 13:27:01 2016 +0300 +++ b/dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/RemoteFileSystemUtils.java Tue Nov 22 16:10:56 2016 +0300 @@ -43,7 +43,9 @@ package org.netbeans.modules.remote.impl.fs; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -53,6 +55,8 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.logging.Level; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment; import org.netbeans.modules.nativeexecution.api.HostInfo; import org.netbeans.modules.nativeexecution.api.util.ConnectionManager; @@ -389,6 +393,49 @@ public static void reportUnexpectedTimeout(TimeoutException ex, String path) { RemoteLogger.getInstance().log(Level.FINE, "Unexpected TimeoutException with zero timeout " + path, ex); } + + /** + * Unpacks a ZIP file to disk. All entries are unpacked, even + * {@code META-INF/MANIFEST.MF} if present. Parent directories are created + * as needed (even if not mentioned in the ZIP); empty ZIP directories are + * created too. Existing files are overwritten. + * + * @param zip a ZIP file + * @param dir the base directory in which to unpack (need not yet exist) + * @throws IOException in case of problems + */ + public static void unpackZipFile(File zip, File dir) throws IOException { + byte[] buf = new byte[8192]; + InputStream is = new FileInputStream(zip); + try { + ZipInputStream zis = new ZipInputStream(is); + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + String name = entry.getName(); + int slash = name.lastIndexOf('/'); + if (slash >= 0) { + File baseDir = new File(dir, name.substring(0, slash).replace('/', File.separatorChar)); + if (!baseDir.isDirectory() && !baseDir.mkdirs()) { + throw new IOException("could not make " + baseDir); + } + } + if (slash != name.length() - 1) { + File f = new File(dir, name.replace('/', File.separatorChar)); + OutputStream os = new FileOutputStream(f); + try { + int read; + while ((read = zis.read(buf)) != -1) { + os.write(buf, 0, read); + } + } finally { + os.close(); + } + } + } + } finally { + is.close(); + } + } // diff -r 13ee6f16f094 -r 45e7429e970a dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/WarmapAdvisorimpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dlight.remote.impl/src/org/netbeans/modules/remote/impl/fs/WarmapAdvisorimpl.java Tue Nov 22 16:10:56 2016 +0300 @@ -0,0 +1,64 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ +package org.netbeans.modules.remote.impl.fs; + +import java.io.File; +import org.netbeans.modules.remote.spi.WarmapAdvisor; +import org.openide.filesystems.FileObject; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author vkvashin + */ +@ServiceProvider(service = WarmapAdvisor.class) +public class WarmapAdvisorimpl implements WarmapAdvisor { + + @Override + public void setWarmupZip(FileObject directory, File zip) { + if (directory instanceof RemoteFileObject) { + RemoteFileObjectBase impl = ((RemoteFileObject) directory).getImplementor(); + if (impl instanceof RemoteDirectory) { + ((RemoteDirectory) impl).setWarmupZip(zip); + } + } + } + +} diff -r 13ee6f16f094 -r 45e7429e970a dlight.remote/src/org/netbeans/modules/remote/spi/WarmapAdvisor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dlight.remote/src/org/netbeans/modules/remote/spi/WarmapAdvisor.java Tue Nov 22 16:10:56 2016 +0300 @@ -0,0 +1,53 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ +package org.netbeans.modules.remote.spi; + +import java.io.File; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.openide.filesystems.FileObject; + +/** + * + * @author vkvashin + */ +public interface WarmapAdvisor { + void setWarmupZip(FileObject directory, File zip); +} diff -r 13ee6f16f094 -r 45e7429e970a dlight.remote/src/org/netbeans/modules/remote/spi/WarmapHintProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dlight.remote/src/org/netbeans/modules/remote/spi/WarmapHintProvider.java Tue Nov 22 16:10:56 2016 +0300 @@ -0,0 +1,67 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ +package org.netbeans.modules.remote.spi; + +import java.io.File; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.openide.filesystems.FileObject; +import org.openide.util.Lookup; + +/** + * + * @author vkvashin + */ +public class WarmapHintProvider { + + private static final Map zips = new ConcurrentHashMap<>(); + + public static void setWarmupZip(FileObject directory, File zip) { + zips.put(directory, zip); + for (WarmapAdvisor wa : Lookup.getDefault().lookupAll(WarmapAdvisor.class)) { + wa.setWarmupZip(directory, zip); + } + } + + public static File getAndRemoveWarmupZip(FileObject directory) { + return zips.remove(directory); + } +}