# HG changeset patch # User Alexander Simon # Date 1320241788 -10800 # Node ID 144cc23a6dc1dc0c81ea5618f132ff022846ae95 # Parent 951d08566353ee8b5fa3ac80b84a47d16d9a556b Third iteration Bug #199806 Provide bridge between remote file system and VCS - renamed ProvidedExtensions2 - delegate proxy operations to remote file system - remove dependency on masterfs - implement all methods diff --git a/fsbridge/build.xml b/fsbridge/build.xml new file mode 100644 --- /dev/null +++ b/fsbridge/build.xml @@ -0,0 +1,5 @@ + + + Builds, tests, and runs the project org.netbeans.modules.fsbridge + + diff --git a/fsbridge/manifest.mf b/fsbridge/manifest.mf new file mode 100644 --- /dev/null +++ b/fsbridge/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.netbeans.modules.fsbridge +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/fsbridge/Bundle.properties +OpenIDE-Module-Specification-Version: 1.0 + diff --git a/fsbridge/nbproject/project.properties b/fsbridge/nbproject/project.properties new file mode 100644 --- /dev/null +++ b/fsbridge/nbproject/project.properties @@ -0,0 +1,2 @@ +javac.source=1.6 +javac.compilerargs=-Xlint -Xlint:-serial diff --git a/fsbridge/nbproject/project.xml b/fsbridge/nbproject/project.xml new file mode 100644 --- /dev/null +++ b/fsbridge/nbproject/project.xml @@ -0,0 +1,32 @@ + + + org.netbeans.modules.apisupport.project + + + org.netbeans.modules.fsbridge + + + org.netbeans.modules.dlight.nativeexecution + + + + 1.10.3 + + + + org.openide.filesystems + + + + 7.47.1 + + + + + org.netbeans.modules.dlight.remote.impl + org.netbeans.modules.versioning + org.netbeans.modules.fsbridge.spi + + + + diff --git a/fsbridge/src/org/netbeans/modules/fsbridge/Bundle.properties b/fsbridge/src/org/netbeans/modules/fsbridge/Bundle.properties new file mode 100644 --- /dev/null +++ b/fsbridge/src/org/netbeans/modules/fsbridge/Bundle.properties @@ -0,0 +1,5 @@ +OpenIDE-Module-Display-Category=Infrastructure +OpenIDE-Module-Long-Description=\ + Remote File System Bridge +OpenIDE-Module-Name=Remote File System Bridge +OpenIDE-Module-Short-Description=Remote File System Bridge diff --git a/fsbridge/src/org/netbeans/modules/fsbridge/spi/Bridge.java b/fsbridge/src/org/netbeans/modules/fsbridge/spi/Bridge.java new file mode 100644 --- /dev/null +++ b/fsbridge/src/org/netbeans/modules/fsbridge/spi/Bridge.java @@ -0,0 +1,106 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2011 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): + * + * Portions Copyrighted 2011 Sun Microsystems, Inc. + */ +package org.netbeans.modules.fsbridge.spi; + +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileStateInvalidException; +import org.openide.filesystems.FileSystem; + +/** + * + * @author Alexander Simon + */ +public final class Bridge { + private Bridge() { + } + + public static FileProxy createLocalFileProxy(final File file) { + return new FileProxy(file.getAbsolutePath(), null); + } + + public static FileProxy createFileProxy(final FileObject file) { + try { + FileProxyOperations fileProxyOperations = getFileProxyOperations(file.getFileSystem()); + if (fileProxyOperations == null) { + return new FileProxy(file.getPath(), null); + } else { + return new FileProxy(file.getPath(), fileProxyOperations); + } + } catch (FileStateInvalidException ex) { + Logger.getLogger(Bridge.class.getName()).log(Level.SEVERE, null, ex); + } + return new FileProxy(file.getPath(), null); + } + + public static FileProxy createFileProxy(FileSystem fs, String path) { + FileProxyOperations fileProxyOperations = getFileProxyOperations(fs); + if (fileProxyOperations == null) { + return new FileProxy(path, null); + } else { + return new FileProxy(path, fileProxyOperations); + } + } + + public static FileObject toFileObject(final FileProxy path) { + return path.toFileObject(); + } + + public static FileProxy normalizeFile(final FileProxy file) { + return file.normalizeFile(); + } + + public static ExecutionEnvironment getExecutionEnvironment(FileProxy file) { + return file.getExecutionEnvironment(); + } + + private static FileProxyOperations getFileProxyOperations(FileSystem fs) { + return (FileProxyOperations) getAttribute(fs, FileProxyOperations.ATTRIBUTE); + } + + private static Object getAttribute(FileSystem fileSystem, String attrName) { + return fileSystem.getRoot().getAttribute(attrName); + } +} diff --git a/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxy.java b/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxy.java new file mode 100644 --- /dev/null +++ b/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxy.java @@ -0,0 +1,170 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2011 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): + * + * Portions Copyrighted 2011 Sun Microsystems, Inc. + */ +package org.netbeans.modules.fsbridge.spi; + +import java.io.File; +import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment; +import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * Represents file on remote or local file system. + * + * @author Alexander Simon + */ +public final class FileProxy { + + private final String path; + private final FileProxyOperations proxy; + + FileProxy(String path, FileProxyOperations proxy) { + this.path = path; + this.proxy = proxy; + } + + public String getAbsolutePath() { + return path; + } + + public String getName() { + if (proxy == null) { + return new File(path).getName(); + } else { + return proxy.getName(this); + } + } + + public boolean isDirectory() { + if (proxy == null) { + return new File(path).isDirectory(); + } else { + return proxy.isDirectory(this); + } + } + + public boolean isFile() { + if (proxy == null) { + return new File(path).isFile(); + } else { + return proxy.isFile(this); + } + } + + public boolean canWrite() { + if (proxy == null) { + return new File(path).canWrite(); + } else { + return proxy.canWrite(this); + } + } + + public FileProxy getParentFile() { + if (proxy == null) { + return Bridge.createLocalFileProxy(new File(path).getParentFile()); + } else { + return proxy.getParentFile(this); + } + } + public boolean exists() { + if (proxy == null) { + return new File(path).exists(); + } else { + return proxy.exists(this); + } + } + + @Override + public String toString() { + return path; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 61 * hash + (this.path != null ? this.path.hashCode() : 0); + hash = 61 * hash + (this.proxy != null ? this.proxy.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FileProxy other = (FileProxy) obj; + if ((this.path == null) ? (other.path != null) : !this.path.equals(other.path)) { + return false; + } + if (this.proxy != other.proxy && (this.proxy == null || !this.proxy.equals(other.proxy))) { + return false; + } + return true; + } + + ExecutionEnvironment getExecutionEnvironment() { + if (proxy == null) { + return ExecutionEnvironmentFactory.getLocal(); + } else { + return proxy.getExecutionEnvironment(); + } + } + + FileObject toFileObject() { + if (proxy == null) { + return FileUtil.toFileObject(new File(FileUtil.normalizePath(path))); + } else { + return proxy.toFileObject(this); + } + } + + FileProxy normalizeFile() { + if (proxy == null) { + return new FileProxy(FileUtil.normalizePath(path), null); + } else { + return proxy.normalize(this); + } + } +} diff --git a/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxyOperations.java b/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxyOperations.java new file mode 100644 --- /dev/null +++ b/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxyOperations.java @@ -0,0 +1,73 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2011 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): + * + * Portions Copyrighted 2011 Sun Microsystems, Inc. + */ +package org.netbeans.modules.fsbridge.spi; + +import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment; +import org.openide.filesystems.FileObject; + +/** + * + * @author Vladimir Voskresensky + */ +public interface FileProxyOperations { + public static final String ATTRIBUTE = "FileProxyOperations"; + + String getName(FileProxy file); + + boolean isDirectory(FileProxy file); + + boolean isFile(FileProxy file); + + boolean canWrite(FileProxy file); + + FileProxy getParentFile(FileProxy file); + + String getAbsolutePath(FileProxy file); + + boolean exists(FileProxy file); + + ExecutionEnvironment getExecutionEnvironment(); + + FileProxy normalize(FileProxy file); + + FileObject toFileObject(FileProxy path); +} diff --git a/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxyOperationsInterceptor.java b/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxyOperationsInterceptor.java new file mode 100644 --- /dev/null +++ b/fsbridge/src/org/netbeans/modules/fsbridge/spi/FileProxyOperationsInterceptor.java @@ -0,0 +1,213 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2011 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): + * + * Portions Copyrighted 2011 Sun Microsystems, Inc. + */ +package org.netbeans.modules.fsbridge.spi; + +import java.io.IOException; +import java.util.List; +import org.openide.filesystems.FileObject; + +/** + * Extension of {@link org.netbeans.modules.masterfs.providers.ProvidedExtensions} to process remote file operations. + * + * @author Alexander Simon + */ +public interface FileProxyOperationsInterceptor { + + public interface FileProxyIOHandler { + /** + * @throws java.io.IOException if handled operation isn't successful + */ + void handle() throws IOException; + } + + public interface FileProxyDeleteHandler { + /** + * Deletes the file or directory denoted by this abstract pathname. If + * this pathname denotes a directory, then the directory must be empty in + * order to be deleted. + * + * @return true if and only if the file or directory is + * successfully deleted; false otherwise + */ + boolean delete(FileProxy file); + } + + + /** + * Return instance of {@link FileProxyOperationsInterceptor.FileProxyIOHandler} + * that is responsible for copying the file or null. + * + * Just the first non null instance of FileProxyIOHandler is used by + * RemoteFileSystem + * + * @param from file to be copied + * @param to target to copy this file to + * @return instance of {@link FileProxyOperationsInterceptor.FileProxyIOHandler} + * that is responsible for copying the file or null + */ + FileProxyOperationsInterceptor.FileProxyIOHandler getCopyHandler(FileProxy from, FileProxy to); + + /** + * Return instance of {@link FileProxyOperationsInterceptor.FileProxyIOHandler} + * that is responsible for moving the file or null. + * + * Just the first non null instance of FileProxyIOHandler is used by + * RemoteFileSystem + * + * @param from file to be moved + * @param to target to move this file to + * @return instance of {@link FileProxyOperationsInterceptor.FileProxyIOHandler} + * that is responsible for moving the file or null + */ + FileProxyOperationsInterceptor.FileProxyIOHandler getMoveHandler(FileProxy from, FileProxy to); + + /* + * Return instance of {@link FileProxyOperationsInterceptor.FileProxyIOHandler} + * that is responsible for renaming the file or null. + * + * Just the first non null instance of FileProxyIOHandler is used by + * RemoteFileSystem + * + * @param from file to be renamed + * @param newName new name of file + * @return instance of {@link FileProxyOperationsInterceptor.FileProxyIOHandler} + * that is responsible for renaming the file or null + */ + FileProxyOperationsInterceptor.FileProxyIOHandler getRenameHandler(FileProxy from, String newName); + + /* + * Return instance of {@link FileProxyOperationsInterceptor.FileProxyDeleteHandler} + * that is responsible for deleting the file or null. + * + * Just the first non null instance of FileProxyDeleteHandler is used by + * RemoteFileSystem + * + * @param f file or folder to be deleted + * @return instance of {@link FileProxyOperationsInterceptor.FileProxyDeleteHandler} + * that is responsible for deleting the file or null + */ + FileProxyOperationsInterceptor.FileProxyDeleteHandler getDeleteHandler(FileProxy f); + + /** + * Called by RemoteFileSystem before FileObject + * is copied + * @param from FileObject to be moved + * @param to FileProxy target to move this file to + */ + void beforeCopy(FileObject from, FileProxy to); + + /** + * Called by RemoteFileSystem after FileObject + * was successfully copied + * @param from FileObject to be moved + * @param to FileProxy target to move this file to + */ + void copySuccess(FileObject from, FileProxy to); + + /** + * Called by RemoteFileSystem after a FileObject + * copy failed + * @param from FileObject to be moved + * @param to FileProxy target to move this file to + */ + void copyFailure(FileObject from, FileProxy to); + + /** + * Called by RemoteFileSystem before FileObject + * is moved + * @param from FileObject to be moved + * @param to FileProxy target to move this file to + */ + void beforeMove(FileObject from, FileProxy to); + + /** + * Called by RemoteFileSystem after FileObject + * was successfully + * @param from FileObject to be moved + * @param to FileProxy target to move this file to + */ + void moveSuccess(FileObject from, FileProxy to); + + /** + * Called by RemoteFileSystem after a FileObject + * move failed + * @param from FileObject to be moved + * @param to FileProxy target to move this file to + */ + void moveFailure(FileObject from, FileProxy to); + + /** + * Called by RemoteFileSystem when FileObject is queried for writability with the + * canWrite() method. + * + * @param f a FileProxy to query + * @return true if the file can be written to, deleted or moved, false otherwise + */ + boolean canWrite(FileProxy f); + + /** + * Called by {@code RemoteFileSystem} when {@code FileObject} is + * queried for attribute and attribute's name starts with {@code ProvidedExtensions} + * prefix. + * @param attrName name of attribute + * @return value of attribute + */ + Object getAttribute(FileProxy file, String attrName); + + /** Allows versioning system to exclude some children from recursive + * listening check. Also notifies the versioning whenever a refresh + * is required and allows the versiniong to provide special timestamp + * for a directory. + *

+ * Default implementation of this method returns -1. + * + * @param dir the directory to check timestamp for + * @param lastTimeStamp the previously known timestamp or -1 + * @param children add subfiles that shall be iterated into this array + * @return the timestamp that shall represent this directory, it will + * be compared with timestamps of all children and the newest + * one will be kept and next time passed as lastTimeStamp. Return + * 0 if the directory does not have any special timestamp. Return + * -1 if you are not providing any special implementation + */ + long refreshRecursively(FileProxy dir, long lastTimeStamp, List children); +}