├── .gitignore ├── src └── com │ └── razorfish │ └── platforms │ └── intellivault │ ├── settings.xml │ ├── utils │ ├── IntelliVaultConstants.java │ └── FileUtils.java │ ├── exceptions │ └── IntelliVaultException.java │ ├── filter │ ├── Filter.java │ └── VaultImportFilter.java │ ├── services │ ├── VaultInvokerService.java │ ├── impl │ │ ├── IntelliVaultPreferencesService.java │ │ ├── VaultInvokerServiceImpl.java │ │ └── IntelliVaultServiceImpl.java │ └── IntelliVaultService.java │ ├── config │ ├── IntelliVaultConfigDefaults.java │ ├── IntelliVaultCRXRepository.java │ ├── IntelliVaultOperationConfig.java │ └── IntelliVaultPreferences.java │ ├── ui │ ├── IntelliVaultRepositorySelector.form │ ├── IntelliVaultRepositorySelector.java │ ├── IntelliVaultSettingsForm.form │ └── IntelliVaultSettings.java │ ├── actions │ ├── VaultOperationDirectory.java │ ├── IntelliVaultExportAction.java │ ├── IntelliVaultImportAction.java │ └── IntelliVaultAbstractAction.java │ ├── config.xml │ └── diff │ └── FileComparator.java ├── .idea └── IntelliVault.iml ├── License.txt ├── README.md └── resources └── META-INF └── plugin.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | 8 | # intelliJ Files 9 | .idea/* 10 | !.idea/IntelliVault.iml 11 | out/ 12 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/utils/IntelliVaultConstants.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.utils; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: sean.steimer 6 | * Date: 4/11/13 7 | * Time: 7:10 PM 8 | * To change this template use File | Settings | File Templates. 9 | */ 10 | public class IntelliVaultConstants { 11 | 12 | /** 13 | * private default constructor to preveent creation of instances 14 | */ 15 | private IntelliVaultConstants() { 16 | //no instances 17 | } 18 | 19 | public static final String JCR_PATH_SEPERATOR = "/"; 20 | 21 | public static final String JCR_ROOT = "jcr_root"; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /.idea/IntelliVault.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | IntelliVault 2 | Copyright (C) 2013 Sean Steimer 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/exceptions/IntelliVaultException.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.exceptions; 2 | 3 | /** 4 | * An General Exception class for Errors that occur in IntelliVault. 5 | * 6 | * @author Sean Steimer 7 | */ 8 | public class IntelliVaultException extends Exception { 9 | 10 | public IntelliVaultException() { 11 | super(); 12 | } 13 | 14 | public IntelliVaultException(String message) { 15 | super(message); 16 | } 17 | 18 | public IntelliVaultException(String message, Throwable cause) { 19 | super(message, cause); 20 | } 21 | 22 | public IntelliVaultException(Throwable cause) { 23 | super(cause); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/filter/Filter.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.filter; 2 | 3 | 4 | /** 5 | * 6 | * An generic interface for filtering a given result set. The intended use is for a filter, or Collection of filters, 7 | * to be passed to some method which uses or generating a result set. Objects where allows() returns false are ignored \ 8 | * from processing. 9 | * 10 | * @param the Type of object to be filtered. 11 | */ 12 | public interface Filter { 13 | /** 14 | * Determine if an object of Type T is allowed by this filter. 15 | * 16 | * @param object an object to be filtered. 17 | * 18 | * @return true if the object is allowed, false if it should be filtered out. 19 | */ 20 | boolean allows(T object); 21 | } 22 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/services/VaultInvokerService.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.services; 2 | 3 | import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: sean.steimer 8 | * Date: 3/17/13 9 | * Time: 9:06 AM 10 | * To change this template use File | Settings | File Templates. 11 | */ 12 | public interface VaultInvokerService { 13 | /** 14 | * Execute a vault command, as specified by the arguments passed in. 15 | * @param vaultPath the path to the vault folder on the file system. 16 | * @param args the arguments which will be used to invoke vault. 17 | * @throws com.razorfish.platforms.intellivault.exceptions.IntelliVaultException if an error occurs during vault execution. 18 | */ 19 | void invokeVault(String vaultPath, String[] args) throws IntelliVaultException; 20 | 21 | /** 22 | * Force vault to re-initialize before next invocation. This should be used when a configuration changes which 23 | * would affect the way vault is called. 24 | */ 25 | void forceReInit(); 26 | } 27 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/config/IntelliVaultConfigDefaults.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.config; 2 | 3 | /** 4 | * Configuration default values used by the app. 5 | */ 6 | public class IntelliVaultConfigDefaults { 7 | 8 | 9 | /** 10 | * Private default constructor to prevent creation of instances of this class. 11 | */ 12 | private IntelliVaultConfigDefaults() { 13 | //no instances 14 | } 15 | 16 | public static final String REPO_NAME = "new repository"; 17 | public static final String REPO_NAME_AUTHOR = "author"; 18 | public static final String REPO_NAME_PUBLISH = "publish"; 19 | 20 | public static final String REPO_URL = "http://localhost:4502"; 21 | public static final String REPO_URL_PUBLISH = "http://localhost:4502"; 22 | public static final String REPO_USER = "admin"; 23 | public static final String REPO_PASSWORD = "admin"; 24 | 25 | public static final String ROOT_FOLDER = "jcr_root"; 26 | public static final String IGNORE_PATTERNS = ".svn,.vlt,CVS,.DS_Store"; 27 | 28 | public static final boolean VERBOSE = true; 29 | public static final boolean CONSOLE_LOG = false; 30 | public static final boolean DEBUG = false; 31 | 32 | public static final boolean SHOW_MESSAGE_DIALOG = true; 33 | 34 | public static final String VAULT_PATH = ""; 35 | } 36 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/filter/VaultImportFilter.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.filter; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import com.intellij.openapi.vfs.VirtualFile; 5 | 6 | import java.util.List; 7 | import java.util.regex.Pattern; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. User: sean.steimer Date: 4/3/13 Time: 2:05 PM To change this template use File | Settings 11 | * | File Templates. 12 | */ 13 | public class VaultImportFilter implements Filter { 14 | private List ignorePatterns; 15 | 16 | private static final Logger log = Logger.getInstance(VaultImportFilter.class); 17 | 18 | /** 19 | * Create a new VaultImportFilter instance based on a List of ignore patterns 20 | * 21 | * @param ignorePatterns the ignore patterns for this filter 22 | */ 23 | public VaultImportFilter(List ignorePatterns) { 24 | this.ignorePatterns = ignorePatterns; 25 | } 26 | 27 | @Override 28 | public boolean allows(VirtualFile file) { 29 | for (String ignorePattern : ignorePatterns) { 30 | boolean matches = file.getName().equals(ignorePattern) || 31 | Pattern.compile(ignorePattern).matcher(file.getName()).matches(); 32 | if (matches) { 33 | log.info(String.format("Skipping file %s, matched ignore pattern %s.", 34 | file.getCanonicalPath(), ignorePattern)); 35 | return false; 36 | } 37 | } 38 | 39 | return true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/services/impl/IntelliVaultPreferencesService.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.services.impl; 2 | 3 | import com.intellij.openapi.components.PersistentStateComponent; 4 | import com.intellij.openapi.components.State; 5 | import com.intellij.openapi.components.Storage; 6 | import com.razorfish.platforms.intellivault.config.IntelliVaultPreferences; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | /** 10 | * The preferences services handles storing and retrieving the configuration state of the vault plugin. 11 | */ 12 | @State(name = "IntelliVaultPreferencesService", storages = { 13 | @Storage(id = "main", file = "$APP_CONFIG$/IntelliVaultPreferencesService.xml") }) 14 | public class IntelliVaultPreferencesService implements PersistentStateComponent { 15 | 16 | private IntelliVaultPreferences preferences; 17 | 18 | public IntelliVaultPreferences getPreferences() { 19 | if (preferences == null) { 20 | preferences = new IntelliVaultPreferences(); 21 | } 22 | 23 | if (preferences.repoConfigList == null || preferences.repoConfigList.size() == 0) { 24 | preferences.repoConfigList = preferences.getDefaultRepos(); 25 | } 26 | 27 | return (IntelliVaultPreferences) preferences.clone(); 28 | } 29 | 30 | public void setPreferences(IntelliVaultPreferences preferences) { 31 | this.preferences = preferences; 32 | } 33 | 34 | @Nullable 35 | @Override 36 | public IntelliVaultPreferences getState() { 37 | return getPreferences(); 38 | } 39 | 40 | @Override 41 | public void loadState(IntelliVaultPreferences preferences) { 42 | setPreferences(preferences); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/ui/IntelliVaultRepositorySelector.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/actions/VaultOperationDirectory.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.actions; 2 | 3 | import com.intellij.psi.PsiDirectory; 4 | import com.razorfish.platforms.intellivault.utils.IntelliVaultConstants; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * User: sean.steimer 9 | * Date: 4/3/13 10 | * Time: 10:42 AM 11 | * To change this template use File | Settings | File Templates. 12 | */ 13 | public class VaultOperationDirectory { 14 | private PsiDirectory psiDir; 15 | private String jcrPath; 16 | 17 | /** 18 | * Create a VaultOperationDirectory instance. 19 | * 20 | * @param psiDir the selected psiDirectory for the vault operation to be executed. 21 | * @param jcrRootFolderName the name of the jcr root foler, to be used for computing the jcr path 22 | */ 23 | public VaultOperationDirectory(PsiDirectory psiDir, String jcrRootFolderName) { 24 | this.psiDir=psiDir; 25 | this.jcrPath=computePathFromPsiDirectory(psiDir,jcrRootFolderName); 26 | } 27 | 28 | public PsiDirectory getPsiDir() { 29 | return psiDir; 30 | } 31 | 32 | public void setPsiDir(PsiDirectory psiDir) { 33 | this.psiDir = psiDir; 34 | } 35 | 36 | public String getJcrPath() { 37 | return jcrPath; 38 | } 39 | 40 | public void setJcrPath(String jcrPath) { 41 | this.jcrPath = jcrPath; 42 | } 43 | 44 | /** 45 | * Compute the operative jcr path that the psiDirectory represents. 46 | * The method calls itself recursively to get the parent path, and then appends the name of the current directory. 47 | * @param psiDir the PsiDirectory used to compute the jcr path 48 | * @param rootDirectoryName the name of the directory representing the jcr root. 49 | * @return the computer jcr path for the folder 50 | */ 51 | private String computePathFromPsiDirectory(PsiDirectory psiDir, String rootDirectoryName) { 52 | 53 | String directoryName = psiDir.getName(); 54 | if(directoryName.equals(rootDirectoryName)) { 55 | return ""; 56 | } 57 | 58 | String parentName = computePathFromPsiDirectory(psiDir.getParentDirectory(),rootDirectoryName); 59 | return parentName + IntelliVaultConstants.JCR_PATH_SEPERATOR + directoryName; 60 | 61 | /* 62 | StringBuilder path = new StringBuilder(); 63 | PsiDirectory curDir = psiDir; 64 | while (!curDir.getName().equals(rootDirectoryName)) { 65 | path.insert(0, "/" + curDir.getName()); 66 | curDir = curDir.getParentDirectory(); 67 | } 68 | 69 | return path.toString(); 70 | */ 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/services/IntelliVaultService.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.services; 2 | 3 | import com.intellij.execution.ui.ConsoleView; 4 | import com.intellij.openapi.progress.ProgressIndicator; 5 | import com.razorfish.platforms.intellivault.actions.VaultOperationDirectory; 6 | import com.razorfish.platforms.intellivault.config.IntelliVaultCRXRepository; 7 | import com.razorfish.platforms.intellivault.config.IntelliVaultOperationConfig; 8 | import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * User: sean.steimer 13 | * Date: 3/15/13 14 | * Time: 1:10 PM 15 | * To change this template use File | Settings | File Templates. 16 | */ 17 | public interface IntelliVaultService { 18 | 19 | /** 20 | * Execute a vault export. 21 | * 22 | * @param repository the crx repository that will be exported from 23 | * @param opConf the configuration operations which will be used for the export 24 | * @param vaultOperationDirectory the directory that will be exported from crx 25 | * @param progressIndicator the progress indicator to be used to inform the user of the operations progress towards 26 | * completion 27 | * @param console the ConsoleView where IntelliVault can log it's output during execution of export 28 | * @throws com.razorfish.platforms.intellivault.exceptions.IntelliVaultException if an error occurs preventing completion 29 | */ 30 | void vaultExport(IntelliVaultCRXRepository repository, IntelliVaultOperationConfig opConf, 31 | VaultOperationDirectory vaultOperationDirectory, ProgressIndicator progressIndicator, 32 | ConsoleView console) 33 | throws IntelliVaultException; 34 | 35 | /** 36 | * Execute a vault import. 37 | * 38 | * @param repository the crx repository that will be imported to 39 | * @param opConf the configuration operations which will be used for the import 40 | * @param vaultOperationDirectory the directory that will be imported to crx 41 | * @param progressIndicator the progress indicator to be used to inform the user of the operations progress towards 42 | * completion 43 | * @param console the ConsoleView where IntelliVault can log it's output during execution of import 44 | * @throws IntelliVaultException if an error occurs preventing completion 45 | */ 46 | void vaultImport(IntelliVaultCRXRepository repository, IntelliVaultOperationConfig opConf, 47 | VaultOperationDirectory vaultOperationDirectory, ProgressIndicator progressIndicator, 48 | ConsoleView console) 49 | throws IntelliVaultException; 50 | } 51 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/config/IntelliVaultCRXRepository.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.config; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * Value object used to store a configured crx repository where vault will import/export. 9 | */ 10 | public class IntelliVaultCRXRepository implements Serializable, Comparable, Cloneable { 11 | 12 | private static final long serialVersionUID = 8008135L; 13 | private String name; 14 | private String repoUrl; 15 | private String username; 16 | private String password; 17 | 18 | /** 19 | * Create a new instance, pre-populating the default values for name, url, username, and password. 20 | */ 21 | public IntelliVaultCRXRepository() { 22 | this.name = IntelliVaultConfigDefaults.REPO_NAME; 23 | this.repoUrl = IntelliVaultConfigDefaults.REPO_URL; 24 | this.password = IntelliVaultConfigDefaults.REPO_PASSWORD; 25 | this.username = IntelliVaultConfigDefaults.REPO_USER; 26 | } 27 | 28 | /** 29 | * Create a new instance with the supplied name, url, username, password. 30 | */ 31 | public IntelliVaultCRXRepository(String name, String repoUrl, String username, String password) { 32 | this.name = name; 33 | this.repoUrl = repoUrl; 34 | this.username = username; 35 | this.password = password; 36 | } 37 | 38 | public String getPassword() { 39 | return password; 40 | } 41 | 42 | public void setPassword(String password) { 43 | this.password = password; 44 | } 45 | 46 | public String getRepoUrl() { 47 | return repoUrl; 48 | } 49 | 50 | public void setRepoUrl(String repoUrl) { 51 | this.repoUrl = repoUrl; 52 | } 53 | 54 | public String getUsername() { 55 | return username; 56 | } 57 | 58 | public void setUsername(String username) { 59 | this.username = username; 60 | } 61 | 62 | public String getName() { 63 | return name; 64 | } 65 | 66 | public void setName(String name) { 67 | this.name = name; 68 | } 69 | 70 | public void replaceWith(IntelliVaultCRXRepository otherRepoConfig) { 71 | this.name = otherRepoConfig.getName(); 72 | this.repoUrl = otherRepoConfig.getRepoUrl(); 73 | this.username = otherRepoConfig.getUsername(); 74 | this.password = otherRepoConfig.getPassword(); 75 | } 76 | 77 | @Override 78 | public int compareTo( 79 | @NotNull 80 | IntelliVaultCRXRepository o) { 81 | return getName().compareTo(o.getName()); 82 | } 83 | 84 | @Override 85 | public Object clone() { 86 | IntelliVaultCRXRepository newRepo = new IntelliVaultCRXRepository(); 87 | newRepo.replaceWith(this); 88 | return newRepo; 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | return name; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 17 | 18 | 19 | 23 | 24 | 25 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/diff/FileComparator.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.diff; 2 | 3 | import com.intellij.openapi.vfs.VirtualFile; 4 | 5 | import java.io.BufferedInputStream; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | 11 | /** 12 | * Compares files to determine if the files are actually different or if the 13 | * differences are due to whitespace only. 14 | */ 15 | public class FileComparator { 16 | 17 | protected boolean ignoreWhitespace; 18 | 19 | /** 20 | * Constructs a new FileComparator. 21 | * 22 | * @param ignoreWhitespace if true ignore files where the only difference is whitepsace, 23 | * if false do a binary check 24 | */ 25 | public FileComparator(boolean ignoreWhitespace) { 26 | this.ignoreWhitespace = ignoreWhitespace; 27 | } 28 | 29 | /** 30 | * Checks to see if the files are equal. If set to ignore whitespace, files 31 | * with only whitespace differences are considered equal. 32 | * 33 | * @param f1 the first file to compare 34 | * @param f2 the second file to compare 35 | * @return true if the files are equal, false otherwise 36 | * @throws IOException 37 | */ 38 | public boolean areEqual(File f1, VirtualFile f2) throws IOException { 39 | if ((f1.exists() && !f2.exists()) || (f2.exists() && !f1.exists())) { 40 | return false; 41 | } 42 | 43 | if (!ignoreWhitespace && f1.length() != f2.getLength()) { 44 | return false; 45 | } 46 | 47 | InputStream f1Is = null; 48 | InputStream f2Is = null; 49 | 50 | try { 51 | f1Is = new BufferedInputStream(new FileInputStream(f1)); 52 | f2Is = f2.getInputStream(); 53 | int f1IsByte = f1Is.read(); 54 | while (f1IsByte != -1) { 55 | int f2IsByte = f2Is.read(); 56 | if (f1IsByte != f2IsByte) { 57 | if (ignoreWhitespace) { 58 | char f1IsChar = (char) f1IsByte; 59 | 60 | while (Character.isWhitespace(f1IsChar)) { 61 | f1IsChar = (char) f1Is.read(); 62 | } 63 | 64 | char f2IsChar = (char) f2IsByte; 65 | while (Character.isWhitespace(f2IsChar)) { 66 | f2IsChar = (char) f2Is.read(); 67 | } 68 | 69 | if (f1IsChar != f2IsChar) { 70 | return false; 71 | } 72 | } else { 73 | return false; 74 | } 75 | } 76 | 77 | f1IsByte = f1Is.read(); 78 | } 79 | 80 | return true; 81 | } finally { 82 | if (f1Is != null) { 83 | f1Is.close(); 84 | } 85 | 86 | if (f2Is != null) { 87 | f2Is.close(); 88 | } 89 | 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IntelliVault 2 | 3 | ## Deprecation Notice 4 | 5 | This plugin is deprecated and no longer updated or supported. It's functionality is largely redundant to that of the [repo tool](https://github.com/Adobe-Marketing-Cloud/tools/tree/master/repo), which can be easily bound to keyboard shortcuts in Intellij by following the steps [here](https://github.com/Adobe-Marketing-Cloud/tools/tree/master/repo#integration-into-intellij). 6 | 7 | You are strongly encouraged to stop using IntelliValut and use repo instead. 8 | 9 | ## About 10 | 11 | A plugin for IntelliJ IDEA to interact with JCR repositories via the FileVault tool which is packaged with Adobe Experience Manager. 12 | 13 | This plugin is largely based upon, and liberally borrows from, [VaultClipse](http://vaultclipse.sourceforge.net/) which is a plugin for the Eclipse IDE for interacting with FileVault. 14 | 15 | The plugin can be found in the [JetBrains IDEA Plugin Repository](http://plugins.jetbrains.com/plugin/7328) 16 | 17 | ## Supported product versions 18 | 19 | The *IntelliVault* plugin is currently supported on the following Intellij products: 20 | 21 | * Intellij IDEA 2016.1 Community/Ultimate 22 | 23 | ## Installation 24 | 25 | To install the plugin using the Intellij built-in plugin management dialog, go to **Preferences** > **Plugins** > **Browse Repositories**, type *Intellivault* and click the **Install** button. 26 | 27 | NOTE: If after installing the plugin and restarting the IDE you don't see the **IntelliVault** option under **Tools** then your version is most likely not supported. 28 | 29 | ## Configuration 30 | 31 | IntelliVault uses the [Filevault](https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/ht-vlttool.html) tool under the covers to transfer content between IDEA and your AEM repository. This is a hard dependency, and requires unpacking Filevault before you can configure the plugin. 32 | 33 | Locate `filevault.zip` or `filevault.tgz` inside of your AEM directory at `crx-quickstart/opt/filevault` and unpack that to any directory. 34 | 35 | Once you have unpacked **Filevault**, open the plugin configuration dialog accessible via **Preferences** > **Tools** > **IntelliVault** and set the following properties. 36 | 37 | - **Vault Directory**: Set this to the directory where you unpacked Filevault, ie. `/Users/myuser/dev/tools/vault/vault-cli-3.1.38/bin` 38 | - **Repository**: See `Multi-Repository Configuration` below 39 | - **Show Operation Confirmation Dialogs**: If checked, IntelliVault will prompt you to comfirm each operation. Uncheck this to remove those confirmations 40 | - Other properties are optional and shouldn't require changes, but should be self-explanatory if/when changes are required 41 | 42 | ### Multi-Repository Configuration 43 | 44 | IntelliVault now allows you to configure and manage multiple repository configurations. For each repo, you must set the following: 45 | 46 | - **Repository Name**: Friendly name for this repo. 47 | - **CRX Repository URL**: URL for the repo, i.e. http://localhost:4502 48 | - **Username/Password**: Credentials used for transferring, ie. admin/admin 49 | 50 | If more than one repo is configured, you will be prompted to select a repo for each operation. If only one repo exists, that repo will be used without any prompt. 51 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/config/IntelliVaultOperationConfig.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.config; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | /** 8 | * Value object for storing vault configuration options such as which files are ignored. 9 | */ 10 | public class IntelliVaultOperationConfig { 11 | 12 | private static final String TEMP_DIR_PROP = "java.io.tmpdir"; 13 | 14 | private String vaultPath; 15 | private String tempDirectory; 16 | private String rootFolderName; 17 | private boolean verbose; 18 | private boolean debug; 19 | private boolean logToConsole; 20 | private List fileIgnorePatterns; 21 | private boolean showMessageDialogs; 22 | 23 | /** 24 | * Create a new instance using the default value for all fields of the operation config 25 | */ 26 | public IntelliVaultOperationConfig() { 27 | this.vaultPath = IntelliVaultConfigDefaults.VAULT_PATH; 28 | this.tempDirectory = System.getProperty(TEMP_DIR_PROP); 29 | this.rootFolderName = IntelliVaultConfigDefaults.ROOT_FOLDER; 30 | this.verbose = IntelliVaultConfigDefaults.VERBOSE; 31 | this.debug = IntelliVaultConfigDefaults.DEBUG; 32 | this.logToConsole = IntelliVaultConfigDefaults.CONSOLE_LOG; 33 | this.fileIgnorePatterns = 34 | new LinkedList(Arrays.asList(IntelliVaultConfigDefaults.IGNORE_PATTERNS.split(","))); 35 | this.showMessageDialogs = IntelliVaultConfigDefaults.SHOW_MESSAGE_DIALOG; 36 | } 37 | 38 | public String getVaultPath() { 39 | return vaultPath; 40 | } 41 | 42 | public void setVaultPath(String vaultPath) { 43 | this.vaultPath = vaultPath; 44 | } 45 | 46 | public String getTempDirectory() { 47 | return tempDirectory; 48 | } 49 | 50 | public void setTempDirectory(String tempDirectory) { 51 | this.tempDirectory = tempDirectory; 52 | } 53 | 54 | public String getRootFolderName() { 55 | return rootFolderName; 56 | } 57 | 58 | public void setRootFolderName(String rootFolderName) { 59 | this.rootFolderName = rootFolderName; 60 | } 61 | 62 | public boolean isVerbose() { 63 | return verbose; 64 | } 65 | 66 | public void setVerbose(boolean verbose) { 67 | this.verbose = verbose; 68 | } 69 | 70 | public boolean isDebug() { 71 | return debug; 72 | } 73 | 74 | public void setDebug(boolean debug) { 75 | this.debug = debug; 76 | } 77 | 78 | public boolean isLogToConsole() { 79 | return logToConsole; 80 | } 81 | 82 | public void setLogToConsole(boolean logToConsole) { 83 | this.logToConsole = logToConsole; 84 | } 85 | 86 | public List getFileIgnorePatterns() { 87 | return fileIgnorePatterns; 88 | } 89 | 90 | public void setFileIgnorePatterns(List fileIgnorePatterns) { 91 | this.fileIgnorePatterns = fileIgnorePatterns; 92 | } 93 | 94 | public boolean showMessageDialogs() { 95 | return showMessageDialogs; 96 | } 97 | 98 | public void setShowMessageDialogs(boolean showMessageDialogs) { 99 | this.showMessageDialogs = showMessageDialogs; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/ui/IntelliVaultRepositorySelector.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.ui; 2 | 3 | import com.intellij.openapi.components.ServiceManager; 4 | import com.intellij.openapi.project.Project; 5 | import com.intellij.openapi.ui.DialogWrapper; 6 | import com.razorfish.platforms.intellivault.actions.IntelliVaultAbstractAction; 7 | import com.razorfish.platforms.intellivault.config.IntelliVaultCRXRepository; 8 | import com.razorfish.platforms.intellivault.config.IntelliVaultPreferences; 9 | import com.razorfish.platforms.intellivault.services.impl.IntelliVaultPreferencesService; 10 | import org.jetbrains.annotations.Nullable; 11 | 12 | import javax.swing.*; 13 | import java.awt.event.ActionEvent; 14 | import java.awt.event.ActionListener; 15 | import java.awt.event.KeyEvent; 16 | import java.util.List; 17 | 18 | public class IntelliVaultRepositorySelector extends DialogWrapper { 19 | 20 | private JPanel contentPane; 21 | private JComboBox comboRepositorySelector; 22 | 23 | private IntelliVaultAbstractAction firingAction; 24 | 25 | public IntelliVaultRepositorySelector(Project project, IntelliVaultAbstractAction myAction) { 26 | super(project); 27 | 28 | firingAction = myAction; 29 | 30 | setModal(true); 31 | 32 | // call onCancel() on ESCAPE; 33 | contentPane.registerKeyboardAction(new ActionListener() { 34 | 35 | @Override 36 | public void actionPerformed(ActionEvent e) { 37 | doCancelAction(); 38 | } 39 | }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 40 | 41 | IntelliVaultPreferencesService preferenceService = 42 | ServiceManager.getService(IntelliVaultPreferencesService.class); 43 | IntelliVaultPreferences preferences = preferenceService.getPreferences(); 44 | List repoList = preferences.getRepoConfigList(); 45 | 46 | String lastUsedRepoName = preferences.lastUsedRepoName; 47 | 48 | int selectIndex = 0; 49 | // Add all configured repositories to the selector. 50 | int index = 0; 51 | for (IntelliVaultCRXRepository repo : repoList) { 52 | comboRepositorySelector.addItem(repo); 53 | if (lastUsedRepoName != null && repo.getName().equals(lastUsedRepoName)) { 54 | selectIndex = index; 55 | } 56 | index++; 57 | } 58 | 59 | comboRepositorySelector.setSelectedIndex(selectIndex); 60 | 61 | setTitle("Choose a CRX Repository"); 62 | 63 | init(); 64 | 65 | } 66 | 67 | @Nullable 68 | @Override 69 | protected JComponent createCenterPanel() { 70 | return contentPane; 71 | } 72 | 73 | @Override 74 | public void doOKAction() { 75 | IntelliVaultCRXRepository selectedRepository = 76 | (IntelliVaultCRXRepository) comboRepositorySelector.getSelectedItem(); 77 | firingAction.setSelectedIntelliVaultCRXRepository(selectedRepository); 78 | 79 | IntelliVaultPreferencesService preferenceService = 80 | ServiceManager.getService(IntelliVaultPreferencesService.class); 81 | IntelliVaultPreferences preferences = preferenceService.getPreferences(); 82 | preferences.lastUsedRepoName = 83 | ((IntelliVaultCRXRepository) comboRepositorySelector.getSelectedItem()).getName(); 84 | preferenceService.setPreferences(preferences); 85 | 86 | super.doOKAction(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | com.crownpartners.intellivault 3 | IntelliVault 4 | 0.10.0 5 | Sean Steimer 6 | 7 | A plugin for IntelliJ IDEA to interact with a CRX repository via the FileVault tool which is 9 | packaged with Adobe AEM/CQ.

10 |

This plugin is largely based upon, and liberally borrows from, VaultClipse 11 | which is a plugin for the Eclipse IDE for interacting with FileVault.

12 |

The plugin source can be found on Github

13 | ]]> 14 |
15 | 16 | 18 |
  • v0.9.1: Added logging of output to the console, removed extraneous dialog options.
  • 19 |
  • v0.9.2: Fixing an issue where the temp directory isn't always deleted.
  • 20 |
  • v0.9.3: Updates to plugin metadata.
  • 21 |
  • v0.9.4: Merged PR from sdehandt; Added option to bypass message dialogs. Also re-branded to Razorfish Platforms and added support for VLT 3.
  • 22 |
  • v0.9.5: Fixed compile version to use JDK 1.6
  • 23 |
  • v0.10.0: Added multiple repository profiles and ability to select from run dialogs.
  • 24 | 25 | ]]> 26 |
    27 | 28 | 29 | 30 | 31 | 33 | 36 | 37 | 41 | 42 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 56 | 57 | 58 | 59 | 61 | 62 | 64 | 65 | 67 | 69 | 70 | 71 | 72 | 73 | com.razorfish.platforms.intellivault.ui.IntelliVaultSettings 74 | 75 | 76 |
    -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/services/impl/VaultInvokerServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.services.impl; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; 5 | import com.razorfish.platforms.intellivault.services.VaultInvokerService; 6 | 7 | import java.io.File; 8 | import java.io.FilenameFilter; 9 | import java.io.IOException; 10 | import java.lang.reflect.Method; 11 | import java.net.URL; 12 | import java.net.URLClassLoader; 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | /** 18 | * The Vault Invoker Service which handles actually calling vault to do import/export operations and dealing with the 19 | * class loaders to do so. 20 | */ 21 | public class VaultInvokerServiceImpl implements VaultInvokerService { 22 | 23 | public static final String LIB = "lib"; 24 | public static final String BIN = "bin"; 25 | private static final String VAULT_CLASS = "com.day.jcr.vault.cli.VaultFsApp"; 26 | private static final String VAULT3_CLASS = "org.apache.jackrabbit.vault.cli.VaultFsApp"; 27 | private static final String VAULT_METHOD = "main"; 28 | private static final Logger log = Logger.getInstance(VaultInvokerServiceImpl.class); 29 | private ClassLoader vaultClassLoader; 30 | private boolean init = false; 31 | private boolean isVault3 = false; 32 | 33 | @Override 34 | public void invokeVault(String vaultDir, String[] args) throws IntelliVaultException { 35 | try { 36 | initVault(vaultDir); 37 | 38 | log.info("executing vlt with params: " + Arrays.toString(args)); 39 | 40 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 41 | 42 | try { 43 | Thread.currentThread().setContextClassLoader(vaultClassLoader); 44 | //figure out which vlt class to use based on version 45 | String vltCLs = isVault3 ? VAULT3_CLASS : VAULT_CLASS; 46 | Class vltClass = Class.forName(vltCLs, true, vaultClassLoader); 47 | Method vltMethod = vltClass.getMethod(VAULT_METHOD, String[].class); 48 | vltMethod.invoke(null, new Object[] { args }); 49 | } finally { 50 | Thread.currentThread().setContextClassLoader(cl); 51 | } 52 | 53 | } catch (Exception e) { 54 | throw new IntelliVaultException(e); 55 | } 56 | } 57 | 58 | @Override 59 | public void forceReInit() { 60 | init = false; 61 | } 62 | 63 | /** 64 | * Initialize vault. Basically finds all the jars in the vault folder and creates a custom class loader which 65 | * includes those jars. All vault operations are then executed using that class loader. 66 | * 67 | * @param vaultDir the vault home directory as specified in the settings dialog. Could be the root directory, or 68 | * potentially the bin or lib directory. 69 | * @throws IOException if an error occurs, such as the vault directory not being set. 70 | */ 71 | private void initVault(String vaultDir) throws IOException { 72 | if (!init) { 73 | if (vaultDir == null || vaultDir.trim().length() == 0) { 74 | throw new IOException("Vault Directory not set"); 75 | } 76 | 77 | if (vaultDir.endsWith(BIN)) { 78 | vaultDir = vaultDir.substring(0, vaultDir.lastIndexOf(File.separator)); 79 | } 80 | 81 | if (!vaultDir.endsWith(LIB)) { 82 | vaultDir += File.separator + LIB; 83 | } 84 | 85 | List libList = new ArrayList(); 86 | File libDir = new File(vaultDir.replace('/', File.separatorChar)); 87 | File[] libs = libDir.listFiles(new FilenameFilter() { 88 | 89 | public boolean accept(File dir, String name) { 90 | return (name.endsWith(".jar")) || (name.endsWith(".zip")); 91 | } 92 | }); 93 | if (libs != null) { 94 | for (File lib : libs) { 95 | try { 96 | libList.add(lib.toURI().toURL()); 97 | String libName = lib.getName(); 98 | if (libName.contains("vault-vlt-3")) { 99 | isVault3 = true; 100 | } 101 | } catch (IOException e) { 102 | log.error("error loading lib " + lib.getAbsolutePath(), e); 103 | } 104 | } 105 | 106 | vaultClassLoader = new URLClassLoader(libList.toArray(new URL[libList.size()])); 107 | init = true; 108 | } 109 | 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/actions/IntelliVaultExportAction.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.actions; 2 | 3 | import com.intellij.execution.filters.TextConsoleBuilderFactory; 4 | import com.intellij.execution.ui.ConsoleView; 5 | import com.intellij.openapi.application.ApplicationManager; 6 | import com.intellij.openapi.progress.ProgressIndicator; 7 | import com.intellij.openapi.progress.Task; 8 | import com.intellij.openapi.project.Project; 9 | import com.intellij.openapi.ui.Messages; 10 | import com.intellij.openapi.wm.ToolWindow; 11 | import com.intellij.openapi.wm.ToolWindowAnchor; 12 | import com.intellij.openapi.wm.ToolWindowManager; 13 | import com.intellij.ui.content.Content; 14 | import com.intellij.ui.content.ContentFactory; 15 | import com.razorfish.platforms.intellivault.config.IntelliVaultCRXRepository; 16 | import com.razorfish.platforms.intellivault.config.IntelliVaultOperationConfig; 17 | import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; 18 | import com.razorfish.platforms.intellivault.services.IntelliVaultService; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | /** 22 | * Created with IntelliJ IDEA. User: sean.steimer Date: 3/13/13 Time: 8:54 PM To 23 | * change this template use File | Settings | File Templates. 24 | */ 25 | public class IntelliVaultExportAction extends IntelliVaultAbstractAction { 26 | 27 | @Override 28 | protected Task getTask(VaultOperationDirectory vaultOpDir, IntelliVaultOperationConfig conf, 29 | IntelliVaultCRXRepository repository, Project project) { 30 | return new IntelliVaultExportTask(vaultOpDir, conf, repository, project); 31 | } 32 | 33 | protected String getDialogMessage() { 34 | return "Export from %s to %s?"; 35 | } 36 | 37 | private class IntelliVaultExportTask extends Task.Backgroundable { 38 | 39 | private VaultOperationDirectory vaultOpDir; 40 | private IntelliVaultOperationConfig conf; 41 | private IntelliVaultCRXRepository repository; 42 | private ConsoleView console; 43 | 44 | public IntelliVaultExportTask(final VaultOperationDirectory vaultOpDir, final IntelliVaultOperationConfig conf, 45 | final IntelliVaultCRXRepository repository, final Project project) { 46 | 47 | super(project, "Running IntelliVault Export Action"); 48 | 49 | this.conf = conf; 50 | this.repository = repository; 51 | this.vaultOpDir = vaultOpDir; 52 | 53 | TextConsoleBuilderFactory factory = TextConsoleBuilderFactory.getInstance(); 54 | this.console = factory.createBuilder(project).getConsole(); 55 | 56 | createToolWindow(project); 57 | 58 | } 59 | 60 | private void createToolWindow(final Project project){ 61 | ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); 62 | String twId = "IntelliVault"; 63 | ToolWindow toolWindow = toolWindowManager.getToolWindow(twId); 64 | if (toolWindow == null) { 65 | toolWindow = toolWindowManager.registerToolWindow(twId, true, ToolWindowAnchor.BOTTOM); 66 | } 67 | 68 | ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); 69 | Content content = contentFactory.createContent(console.getComponent(), "", false); 70 | 71 | toolWindow.getContentManager().addContent(content); 72 | toolWindow.getContentManager().setSelectedContent(content); 73 | //TODO toolWindow.setIcon(); 74 | 75 | toolWindow.show(new Runnable() { 76 | @Override 77 | public void run() { 78 | // Do nothing 79 | } 80 | }); 81 | } 82 | 83 | @Override 84 | public void run(@NotNull ProgressIndicator progressIndicator) { 85 | final IntelliVaultService vaultService = getVaultService(); 86 | try { 87 | vaultService.vaultExport(repository, conf, vaultOpDir, progressIndicator, console); 88 | 89 | if (conf.showMessageDialogs()) { 90 | ApplicationManager.getApplication().invokeLater(new Runnable() { 91 | @Override 92 | public void run() { 93 | Messages.showInfoMessage(String.format("Successfully Exported from %s.", 94 | repository.getRepoUrl() + vaultOpDir.getJcrPath()), 95 | "IntelliVault Export Completed Successfully!"); 96 | } 97 | }); 98 | } 99 | } catch (final IntelliVaultException e) { 100 | ApplicationManager.getApplication().invokeLater(new Runnable() { 101 | @Override 102 | public void run() { 103 | Messages.showErrorDialog(e.getLocalizedMessage(), "IntelliVault Error!"); 104 | } 105 | }); 106 | 107 | } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/actions/IntelliVaultImportAction.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.actions; 2 | 3 | import com.intellij.execution.filters.TextConsoleBuilderFactory; 4 | import com.intellij.execution.ui.ConsoleView; 5 | import com.intellij.openapi.application.ApplicationManager; 6 | import com.intellij.openapi.progress.ProgressIndicator; 7 | import com.intellij.openapi.progress.Task; 8 | import com.intellij.openapi.project.Project; 9 | import com.intellij.openapi.ui.Messages; 10 | import com.intellij.openapi.wm.ToolWindow; 11 | import com.intellij.openapi.wm.ToolWindowAnchor; 12 | import com.intellij.openapi.wm.ToolWindowManager; 13 | import com.intellij.ui.content.Content; 14 | import com.intellij.ui.content.ContentFactory; 15 | import com.razorfish.platforms.intellivault.config.IntelliVaultCRXRepository; 16 | import com.razorfish.platforms.intellivault.config.IntelliVaultOperationConfig; 17 | import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; 18 | import com.razorfish.platforms.intellivault.services.IntelliVaultService; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | /** 22 | * Created with IntelliJ IDEA. 23 | * User: sean.steimer 24 | * Date: 3/13/13 25 | * Time: 8:44 PM 26 | * To change this template use File | Settings | File Templates. 27 | */ 28 | public class IntelliVaultImportAction extends IntelliVaultAbstractAction { 29 | 30 | @Override 31 | protected Task getTask(VaultOperationDirectory vaultOpDir, IntelliVaultOperationConfig conf, 32 | IntelliVaultCRXRepository repository, Project project) { 33 | return new IntelliVaultImportTask(vaultOpDir, conf, repository, project); 34 | } 35 | 36 | protected String getDialogMessage() { 37 | return "Import to %s from %s?"; 38 | } 39 | 40 | /** 41 | * The Task that executes the Import in the Background. 42 | */ 43 | private class IntelliVaultImportTask extends Task.Backgroundable { 44 | 45 | private VaultOperationDirectory vaultOpDir; 46 | private IntelliVaultOperationConfig conf; 47 | private IntelliVaultCRXRepository repository; 48 | private ConsoleView console; 49 | 50 | /** 51 | * Construct the Instance to be executed. 52 | * 53 | * @param vaultOpDir the Vault Operation Directory 54 | * @param conf the Vault Configuration Options 55 | * @param repository the CRX Repository to import into 56 | * @param project the IntelliJ Project 57 | */ 58 | public IntelliVaultImportTask(VaultOperationDirectory vaultOpDir, IntelliVaultOperationConfig conf, 59 | IntelliVaultCRXRepository repository, Project project) { 60 | super(project, "Running IntelliVault Import Action"); 61 | this.conf = conf; 62 | this.repository = repository; 63 | this.vaultOpDir = vaultOpDir; 64 | 65 | TextConsoleBuilderFactory factory = TextConsoleBuilderFactory.getInstance(); 66 | this.console = factory.createBuilder(project).getConsole(); 67 | 68 | ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); 69 | String twId = "IntelliVault"; 70 | ToolWindow toolWindow = toolWindowManager.getToolWindow(twId); 71 | if (toolWindow == null) { 72 | toolWindow = toolWindowManager.registerToolWindow(twId, true, ToolWindowAnchor.BOTTOM); 73 | } 74 | 75 | 76 | ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); 77 | Content content = contentFactory.createContent(console.getComponent(), "", false); 78 | 79 | toolWindow.getContentManager().addContent(content); 80 | toolWindow.getContentManager().setSelectedContent(content); 81 | //TODO toolWindow.setIcon(); 82 | 83 | toolWindow.show(new Runnable() { 84 | @Override 85 | public void run() { 86 | //To change body of implemented methods use File | Settings | File Templates. 87 | } 88 | }); 89 | } 90 | 91 | @Override 92 | public void run(@NotNull ProgressIndicator progressIndicator) { 93 | IntelliVaultService vaultService = getVaultService(); 94 | try { 95 | vaultService.vaultImport(repository, conf, vaultOpDir, progressIndicator, console); 96 | if (conf.showMessageDialogs()) { 97 | ApplicationManager.getApplication().invokeLater(new Runnable() { 98 | @Override 99 | public void run() { 100 | Messages.showInfoMessage(String.format("Successfully Imported to %s.", 101 | new Object[]{repository.getRepoUrl() + vaultOpDir.getJcrPath()}), 102 | "IntelliVault Import Completed Successfully!" 103 | ); 104 | } 105 | }); 106 | } 107 | } 108 | catch (final IntelliVaultException e) { 109 | ApplicationManager.getApplication().invokeLater(new Runnable() { 110 | @Override 111 | public void run() { 112 | Messages.showErrorDialog(e.getLocalizedMessage(), "IntelliVault Error!"); 113 | } 114 | }); 115 | 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/actions/IntelliVaultAbstractAction.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.actions; 2 | 3 | import com.intellij.ide.IdeView; 4 | import com.intellij.openapi.actionSystem.AnAction; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import com.intellij.openapi.actionSystem.LangDataKeys; 7 | import com.intellij.openapi.actionSystem.PlatformDataKeys; 8 | import com.intellij.openapi.components.ServiceManager; 9 | import com.intellij.openapi.diagnostic.Logger; 10 | import com.intellij.openapi.progress.ProgressManager; 11 | import com.intellij.openapi.progress.Task; 12 | import com.intellij.openapi.project.Project; 13 | import com.intellij.openapi.ui.DialogWrapper; 14 | import com.intellij.openapi.ui.Messages; 15 | import com.intellij.psi.PsiDirectory; 16 | import com.razorfish.platforms.intellivault.config.IntelliVaultCRXRepository; 17 | import com.razorfish.platforms.intellivault.config.IntelliVaultOperationConfig; 18 | import com.razorfish.platforms.intellivault.config.IntelliVaultPreferences; 19 | import com.razorfish.platforms.intellivault.services.IntelliVaultService; 20 | import com.razorfish.platforms.intellivault.services.impl.IntelliVaultPreferencesService; 21 | import com.razorfish.platforms.intellivault.ui.IntelliVaultRepositorySelector; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * Created with IntelliJ IDEA. 27 | * User: sean.steimer 28 | * Date: 3/15/13 29 | * Time: 1:31 PM 30 | * To change this template use File | Settings | File Templates. 31 | */ 32 | public abstract class IntelliVaultAbstractAction extends AnAction { 33 | 34 | private static final Logger log = Logger.getInstance(IntelliVaultAbstractAction.class); 35 | /** 36 | * The selected CRX repository from the select dialog. 37 | */ 38 | private IntelliVaultCRXRepository crxRepository; 39 | 40 | @Override 41 | public void update(final AnActionEvent evt) { 42 | PsiDirectory directory = getCRXDirectory(evt); 43 | //if directory is null (no jcr directory selected) or the directory is the jcr root, don't let them proceed. 44 | if (directory == null || directory.getName().equals(getIntelliVaultConfig().getRootFolderName())) { 45 | evt.getPresentation().setEnabled(false); 46 | } 47 | 48 | } 49 | 50 | public void actionPerformed(final AnActionEvent evt) { 51 | 52 | final IntelliVaultOperationConfig conf = getIntelliVaultConfig(); 53 | 54 | final IntelliVaultPreferences preferences = 55 | ServiceManager.getService(IntelliVaultPreferencesService.class).getPreferences(); 56 | 57 | // A user must config their repositories before using the tool. 58 | if (preferences.hasRepositoryConfigs()) { 59 | final PsiDirectory psiDir = getCRXDirectory(evt); 60 | final VaultOperationDirectory vaultOpDir = new VaultOperationDirectory(psiDir, conf.getRootFolderName()); 61 | Project project = evt.getData(PlatformDataKeys.PROJECT); 62 | 63 | List repoConfigList = preferences.getRepoConfigList(); 64 | if (repoConfigList.size() > 1) { 65 | // Shows the dialog that lets the user select one of their configured CRX Repositories. 66 | final IntelliVaultRepositorySelector form = new IntelliVaultRepositorySelector(project, this); 67 | form.show(); 68 | log.info("form exit code is " + form.getExitCode() + " we need " + DialogWrapper.OK_EXIT_CODE); 69 | if (form.getExitCode() == DialogWrapper.OK_EXIT_CODE) { 70 | IntelliVaultCRXRepository repository = getSelectedIntelliVaultCRXRepository(); 71 | runAction(conf, vaultOpDir, project, repository); 72 | } else { 73 | log.debug("User canceled action"); 74 | } 75 | } else { 76 | IntelliVaultCRXRepository repository = repoConfigList.get(0); 77 | runAction(conf, vaultOpDir, project, repository); 78 | } 79 | } else { 80 | Messages.showErrorDialog( 81 | "You haven't set up any repositories yet. Go to File > Settings > IntelliVault to setup your repositories.", 82 | "Cannot Perform Action"); 83 | } 84 | } 85 | 86 | private void runAction(IntelliVaultOperationConfig conf, VaultOperationDirectory vaultOpDir, Project project, 87 | IntelliVaultCRXRepository repository) { 88 | if (repository != null) { 89 | boolean proceed = !conf.showMessageDialogs() || (Messages.showYesNoDialog( 90 | String.format(getDialogMessage(), repository.getRepoUrl() + vaultOpDir.getJcrPath(), 91 | vaultOpDir.getPsiDir().getVirtualFile().getCanonicalPath()), "Run IntelliVault?", 92 | Messages.getQuestionIcon()) == Messages.YES); 93 | if (proceed) { 94 | ProgressManager.getInstance().run(getTask(vaultOpDir, conf, repository, project)); 95 | } else { 96 | log.debug("User canceled action after selecting a repository"); 97 | } 98 | } else { 99 | log.warn("Cannot continue, selected repository is null"); 100 | } 101 | } 102 | 103 | protected abstract Task getTask(VaultOperationDirectory vaultOpDir, IntelliVaultOperationConfig conf, 104 | IntelliVaultCRXRepository repository, Project project); 105 | 106 | protected abstract String getDialogMessage(); 107 | 108 | protected PsiDirectory getCRXDirectory(AnActionEvent evt) { 109 | IdeView ideView = evt.getData(LangDataKeys.IDE_VIEW); 110 | if (ideView != null) { 111 | PsiDirectory[] directories = ideView.getDirectories(); 112 | if (directories != null && directories.length == 1) { 113 | PsiDirectory directory = directories[0]; 114 | String rootFolderName = getIntelliVaultConfig().getRootFolderName(); 115 | 116 | PsiDirectory curDir = directory; 117 | while (curDir != null) { 118 | if (curDir.getName().equals(rootFolderName)) { 119 | return directory; 120 | } 121 | curDir = curDir.getParentDirectory(); 122 | } 123 | 124 | } 125 | } 126 | 127 | return null; 128 | } 129 | 130 | protected IntelliVaultService getVaultService() { 131 | return ServiceManager.getService(IntelliVaultService.class); 132 | } 133 | 134 | protected IntelliVaultOperationConfig getIntelliVaultConfig() { 135 | IntelliVaultPreferencesService preferences = ServiceManager.getService(IntelliVaultPreferencesService.class); 136 | return preferences.getPreferences().getOperationConfig(); 137 | } 138 | 139 | /** 140 | * Gets the selected CRX repository from the {@link IntelliVaultRepositorySelector} that is shown when an action is executed. 141 | * 142 | * @return The selected {@link IntelliVaultCRXRepository} or null if the selection was cancelled. 143 | */ 144 | public IntelliVaultCRXRepository getSelectedIntelliVaultCRXRepository() { 145 | return crxRepository; 146 | } 147 | 148 | /** 149 | * Sets the selected CRX repository from the {@link IntelliVaultRepositorySelector} that is shown when an action is executed. 150 | * 151 | * @param crxRepository The {@link IntelliVaultCRXRepository} to mark as selected. 152 | */ 153 | public void setSelectedIntelliVaultCRXRepository(IntelliVaultCRXRepository crxRepository) { 154 | this.crxRepository = crxRepository; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/config/IntelliVaultPreferences.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.config; 2 | 3 | import com.razorfish.platforms.intellivault.services.impl.IntelliVaultPreferencesService; 4 | 5 | import java.io.IOException; 6 | import java.io.Serializable; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.LinkedList; 10 | import java.util.List; 11 | 12 | /** 13 | * Value object for storing all Intellivault user preferences. 14 | */ 15 | public class IntelliVaultPreferences implements Serializable, Cloneable { 16 | 17 | private static final long serialVersionUID = -7299400926047258802L; 18 | 19 | public String vaultPath; 20 | public String tempDirectory; 21 | public String rootFolderName; 22 | public boolean verbose; 23 | public boolean showDialogs; 24 | public boolean debug; 25 | public boolean logToConsole; 26 | public List fileIgnorePatterns; 27 | 28 | public List repoConfigList; 29 | public String lastUsedRepoName; 30 | 31 | /** 32 | * Create a default preferences object. 33 | */ 34 | public IntelliVaultPreferences() { 35 | IntelliVaultOperationConfig operationConfig = new IntelliVaultOperationConfig(); 36 | this.vaultPath = operationConfig.getVaultPath(); 37 | this.tempDirectory = operationConfig.getTempDirectory(); 38 | this.rootFolderName = operationConfig.getRootFolderName(); 39 | 40 | this.verbose = operationConfig.isVerbose(); 41 | this.debug = operationConfig.isDebug(); 42 | this.showDialogs = operationConfig.showMessageDialogs(); 43 | this.logToConsole = operationConfig.isLogToConsole(); 44 | 45 | this.fileIgnorePatterns = operationConfig.getFileIgnorePatterns(); 46 | this.repoConfigList = new LinkedList<>(); 47 | this.lastUsedRepoName = null; 48 | } 49 | 50 | /** 51 | * Get the applicable IntelliVaultOperationConfig from this IntelliVaultPreferences object. 52 | * 53 | * @return the operation config 54 | */ 55 | public IntelliVaultOperationConfig getOperationConfig() { 56 | 57 | IntelliVaultOperationConfig operationConfig = new IntelliVaultOperationConfig(); 58 | operationConfig.setVaultPath(this.vaultPath); 59 | operationConfig.setTempDirectory(this.tempDirectory); 60 | operationConfig.setRootFolderName(this.rootFolderName); 61 | 62 | operationConfig.setVerbose(this.verbose); 63 | operationConfig.setLogToConsole(this.logToConsole); 64 | operationConfig.setDebug(this.debug); 65 | operationConfig.setShowMessageDialogs(this.showDialogs); 66 | 67 | operationConfig.setFileIgnorePatterns(this.fileIgnorePatterns); 68 | 69 | return operationConfig; 70 | } 71 | 72 | /** 73 | * Convenience method for putting a {@link IntelliVaultCRXRepository} on the list. 74 | * 75 | * @param repoName The name of the repository to put. 76 | * @param url The url of the repository to put. 77 | * @param username The username of the repository to put. 78 | * @param password The password of the repository to put. 79 | * @return The newly put or updated {@link IntelliVaultCRXRepository} 80 | * @see IntelliVaultPreferences#putRepositoryConfiguration(String, String, String, String) 81 | */ 82 | public IntelliVaultCRXRepository putRepositoryConfiguration(final String repoName, final String url, 83 | final String username, final String password) { 84 | IntelliVaultCRXRepository repo = new IntelliVaultCRXRepository(repoName, url, username, password); 85 | return putRepositoryConfiguration(repo); 86 | } 87 | 88 | /** 89 | * Puts a {@link IntelliVaultCRXRepository} on the list. 90 | * This method is called 'put' because like a map, it will replace an existing value (treating {@link IntelliVaultCRXRepository#getName()} like a key) 91 | * 92 | * @param repo The {@link IntelliVaultCRXRepository} to put on the repository list. 93 | * @return The {@link IntelliVaultCRXRepository} that was just put on the list. 94 | */ 95 | public IntelliVaultCRXRepository putRepositoryConfiguration(IntelliVaultCRXRepository repo) { 96 | IntelliVaultCRXRepository existing = getRepositoryConfiguration(repo.getName()); 97 | if (existing != null) { 98 | // Keep list order 99 | existing.replaceWith(repo); 100 | return existing; 101 | } else { 102 | repoConfigList.add(repo); 103 | } 104 | return repo; 105 | } 106 | 107 | public void removeRepositoryConfiguration(final String repoName) { 108 | IntelliVaultCRXRepository repository = getRepositoryConfiguration(repoName); 109 | this.repoConfigList.remove(repository); 110 | } 111 | 112 | public IntelliVaultCRXRepository getRepositoryConfiguration(final String repoName) { 113 | for (IntelliVaultCRXRepository repo : repoConfigList) { 114 | if (repo.getName().equals(repoName)) { 115 | return repo; 116 | } 117 | } 118 | return null; 119 | } 120 | 121 | public List getRepoConfigList() { 122 | return repoConfigList; 123 | } 124 | 125 | public String getLastUsedRepoName() { 126 | return lastUsedRepoName; 127 | } 128 | 129 | /** 130 | * Convenience method to return the first {@link IntelliVaultCRXRepository} or null if none are setup yet. 131 | * 132 | * @return The first {@link IntelliVaultCRXRepository} in the settings list (after alphabetical sorting) 133 | */ 134 | public IntelliVaultCRXRepository getFirstRepositoryConfiguration() { 135 | return repoConfigList.size() > 0 ? repoConfigList.get(0) : null; 136 | } 137 | 138 | /** 139 | * Convenience method for determining if there are any {@link IntelliVaultCRXRepository} configurations setup yet. 140 | */ 141 | public boolean hasRepositoryConfigs() { 142 | return !getRepoConfigList().isEmpty(); 143 | } 144 | 145 | /** 146 | * After deserialization this will sort the repository list by name. 147 | * 148 | * @param in The deserialized preferences. 149 | */ 150 | private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { 151 | 152 | Collections.sort(getRepoConfigList()); 153 | 154 | in.defaultReadObject(); 155 | } 156 | 157 | /** 158 | * Clones this preferences object. Need to do this when loading the settings so that changes can be cancelled, 159 | * otherwise updating this object will auto-save (since it likely references the deserialized object) 160 | * 161 | * @return A deep clone of this preferences object. 162 | * @see IntelliVaultPreferencesService#getPreferences() 163 | */ 164 | @Override 165 | public Object clone() { 166 | IntelliVaultPreferences prefs = new IntelliVaultPreferences(); 167 | prefs.vaultPath = vaultPath; 168 | 169 | prefs.tempDirectory = tempDirectory; 170 | prefs.rootFolderName = rootFolderName; 171 | prefs.verbose = verbose; 172 | prefs.showDialogs = showDialogs; 173 | prefs.debug = debug; 174 | prefs.logToConsole = logToConsole; 175 | if (fileIgnorePatterns != null) { 176 | prefs.fileIgnorePatterns.clear(); // Remove defaults 177 | prefs.fileIgnorePatterns.addAll(fileIgnorePatterns); 178 | } 179 | 180 | if (repoConfigList != null) { 181 | for (IntelliVaultCRXRepository repo : repoConfigList) { 182 | prefs.repoConfigList.add((IntelliVaultCRXRepository) repo.clone()); 183 | } 184 | } 185 | 186 | prefs.lastUsedRepoName = this.lastUsedRepoName; 187 | 188 | return prefs; 189 | } 190 | 191 | public List getDefaultRepos() { 192 | List repos = new ArrayList<>(); 193 | 194 | IntelliVaultCRXRepository author = new IntelliVaultCRXRepository(); 195 | author.setName(IntelliVaultConfigDefaults.REPO_NAME_AUTHOR); 196 | repos.add(author); 197 | 198 | IntelliVaultCRXRepository publish = new IntelliVaultCRXRepository(); 199 | publish.setName(IntelliVaultConfigDefaults.REPO_NAME_PUBLISH); 200 | publish.setRepoUrl(IntelliVaultConfigDefaults.REPO_URL_PUBLISH); 201 | repos.add(publish); 202 | 203 | return repos; 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.utils; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.util.Computable; 5 | import com.intellij.openapi.util.ThrowableComputable; 6 | import com.intellij.openapi.vfs.VirtualFile; 7 | import com.intellij.psi.PsiDirectory; 8 | import com.intellij.psi.PsiFile; 9 | import com.razorfish.platforms.intellivault.diff.FileComparator; 10 | import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; 11 | import com.razorfish.platforms.intellivault.filter.Filter; 12 | 13 | import java.io.File; 14 | import java.io.FileInputStream; 15 | import java.io.FileOutputStream; 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.OutputStream; 19 | 20 | /** 21 | * FileUtils is a set of static utility methods for interacting with files. 22 | * Both files on the file system before/after a vault import/export operation, 23 | * and virtual files within the intelliJ IDEA Project file system. 24 | */ 25 | public class FileUtils { 26 | 27 | public static final int BUFFER_LENGTH = 1024; 28 | private static final String VAULTCLIPSE_TEMP_DIR_NAME = "IntelliVault"; 29 | private static final boolean IGNORE_WHITESPACE = false; 30 | 31 | /** 32 | * Private default constructor, prevents creating instances 33 | */ 34 | private FileUtils() { 35 | 36 | } 37 | 38 | /** 39 | * Create a temporary directory on the file system, which will be used as 40 | * the base directory for a vault operation. 41 | * 42 | * @param userTempDir the user's temporary directory, where the tempdir will be 43 | * created. 44 | * @return a java.io.File instance representing the newly created directory. 45 | */ 46 | public static File createTempDirectory(String userTempDir) { 47 | File baseDir = new File(userTempDir + File.separator + VAULTCLIPSE_TEMP_DIR_NAME + File.separator + System 48 | .currentTimeMillis()); 49 | baseDir.mkdirs(); 50 | 51 | return baseDir; 52 | } 53 | 54 | /** 55 | * Copy the contents of an import operation from the IDEA project directory 56 | * to the vault temp directory. 57 | * 58 | * @param importBaseDir the file system directory, which serves as the root of the 59 | * copy target 60 | * @param importDir the PsiDirectory (IDEA virtual directory) containing the 61 | * contents to be copied 62 | * @param path the jcr path representing the root of the import 63 | * @param filter A list of Filters specifying which files should be ignored 64 | * (not imported). 65 | * @throws com.razorfish.platforms.intellivault.exceptions.IntelliVaultException if an error occurs during copy 66 | */ 67 | public static void copyImportContents(File importBaseDir, PsiDirectory importDir, String path, 68 | Filter filter) throws IntelliVaultException { 69 | File copyRootDir = new File( 70 | importBaseDir.getAbsolutePath() + File.separator + IntelliVaultConstants.JCR_ROOT + path 71 | .replace(IntelliVaultConstants.JCR_PATH_SEPERATOR, File.separator)); 72 | copyRootDir.mkdirs(); 73 | 74 | try { 75 | copyImportContents(copyRootDir, importDir.getVirtualFile(), filter); 76 | } catch (IOException e) { 77 | throw new IntelliVaultException("Failed copying contents.", e); 78 | } 79 | } 80 | 81 | /** 82 | * Recursive method called for copying import contents from the IDEA project 83 | * directory to the vault temp directory. For each child of virtualFile, if 84 | * it is a directory, a new directory is created in fsDir, and this method 85 | * is called recursively. If the child is a file, then that file is created 86 | * and the content copied. 87 | * 88 | * @param fsDir th file system directory where contents will be copied 89 | * @param virtualFile the VirtualFile in the IDEA project being copied to fsDir. In 90 | * practice this is always a directory. 91 | * @param filter A list of Filters specifying which files should be ignored 92 | * (not imported). 93 | * @throws IOException if an error occurs during copy 94 | */ 95 | private static void copyImportContents(File fsDir, VirtualFile virtualFile, Filter filter) 96 | throws IOException { 97 | VirtualFile[] contents = virtualFile.getChildren(); 98 | for (int i = 0; i < contents.length; i++) { 99 | VirtualFile file = contents[i]; 100 | if (filter.allows(file)) { 101 | if (file.isDirectory()) { 102 | File newDir = new File(fsDir.getAbsolutePath() + File.separator + file.getName()); 103 | newDir.mkdir(); 104 | copyImportContents(newDir, file, filter); 105 | } else { 106 | InputStream ins = null; 107 | try { 108 | ins = file.getInputStream(); 109 | writeFile(file.getInputStream(), fsDir.getAbsolutePath() + File.separator + file.getName()); 110 | } finally { 111 | if (ins != null) { 112 | ins.close(); 113 | ; 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } 120 | 121 | public static void copyExportContents(final PsiDirectory exportDir, final File exportBaseDir, final String path) 122 | throws IntelliVaultException { 123 | final File copyRootDir = new File( 124 | exportBaseDir.getAbsolutePath() + File.separator + IntelliVaultConstants.JCR_ROOT + path 125 | .replace(IntelliVaultConstants.JCR_PATH_SEPERATOR, File.separator)); 126 | if (!copyRootDir.exists()) { 127 | throw new IntelliVaultException("Failed copying contents."); 128 | } 129 | 130 | try { 131 | copyExportContents(exportDir, copyRootDir); 132 | } catch (IOException e) { 133 | throw new IntelliVaultException("Error Copying Exported contents to IDEA.", e); 134 | } 135 | exportDir.getVirtualFile().refresh(false, true); 136 | } 137 | 138 | /** 139 | * Delete a directory and all of it's contents in a depth-first recursive manner. 140 | * 141 | * @param f the directory to delete 142 | * @throws IOException if an error occurs 143 | */ 144 | public static void deleteDirectoryRecursive(File f) throws IOException { 145 | if (f.isDirectory()) { 146 | for (File c : f.listFiles()) { 147 | deleteDirectoryRecursive(c); 148 | } 149 | } 150 | 151 | //once we have deleted all of a directories contents, we delete the directory 152 | delete(f); 153 | 154 | } 155 | 156 | /** 157 | * Delete a file. This method will retry the delete up to 5 times, sleeping for one second between retries. 158 | * This is because sometimes, especially with smaller imports, the cleanup starts happening before vault has closed 159 | * all of it's file locks. The retry behavior makes a best effort to properly cleanup when that happens. 160 | * 161 | * @param f the file to delete 162 | * @throws IOException if the file can't be deleted. 163 | */ 164 | private static void delete(File f) throws IOException { 165 | boolean isDeleted = f.delete(); 166 | for (int i = 0; i < 4 && !isDeleted; i++) { 167 | try { 168 | Thread.sleep(1000); 169 | } catch (InterruptedException e) { 170 | throw new IOException("Failed to delete file: " + f, e); 171 | } 172 | isDeleted = f.delete(); 173 | } 174 | 175 | if (!isDeleted) { 176 | throw new IOException("Failed to delete file: " + f); 177 | } 178 | } 179 | 180 | private static void copyExportContents(final PsiDirectory exportDir, File copyRootDir) throws IOException { 181 | File[] contents = copyRootDir.listFiles(); 182 | FileComparator comparator = new FileComparator(IGNORE_WHITESPACE); 183 | for (int i = 0; i < contents.length; i++) { 184 | final File f = contents[i]; 185 | if (f.isDirectory()) { 186 | PsiDirectory subdir = exportDir.findSubdirectory(f.getName()); 187 | 188 | if (subdir == null) { 189 | subdir = ApplicationManager.getApplication().runWriteAction(new Computable() { 190 | 191 | @Override 192 | public PsiDirectory compute() { 193 | return exportDir.createSubdirectory(f.getName()); 194 | } 195 | }); 196 | } 197 | copyExportContents(subdir, f); 198 | } else { 199 | copyFile(exportDir, f, comparator); 200 | } 201 | } 202 | } 203 | 204 | private static void copyFile(final PsiDirectory exportDir, final File f, FileComparator comparator) 205 | throws IOException { 206 | if (f.getName().equals(".vlt")) { 207 | return; 208 | } 209 | 210 | PsiFile file = exportDir.findFile(f.getName()); 211 | 212 | if (file == null) { 213 | file = ApplicationManager.getApplication().runWriteAction(new Computable() { 214 | 215 | @Override 216 | public PsiFile compute() { 217 | return exportDir.createFile(f.getName()); 218 | } 219 | }); 220 | } 221 | 222 | if (!comparator.areEqual(f, file.getVirtualFile())) { 223 | copyFileContents(file, f); 224 | } 225 | 226 | } 227 | 228 | private static void copyFileContents(final PsiFile file, final File f) throws IOException { 229 | final VirtualFile vf = file.getVirtualFile(); 230 | 231 | ApplicationManager.getApplication().runWriteAction(new ThrowableComputable() { 232 | 233 | @Override 234 | public Void compute() throws IOException { 235 | OutputStream out = null; 236 | InputStream in = null; 237 | try { 238 | out = vf.getOutputStream(ApplicationManager.getApplication()); 239 | in = new FileInputStream(f); 240 | write(in, out); 241 | } finally { 242 | if (out != null) { 243 | out.flush(); 244 | out.close(); 245 | } 246 | 247 | if (in != null) { 248 | in.close(); 249 | } 250 | } 251 | return null; 252 | } 253 | }); 254 | 255 | } 256 | 257 | public static void writeFile(String inputResourcePath, String filePath) throws IOException { 258 | InputStream ins = null; 259 | try { 260 | ins = FileUtils.class.getClassLoader().getResourceAsStream(inputResourcePath); 261 | writeFile(ins, filePath); 262 | } finally { 263 | if (ins != null) { 264 | ins.close(); 265 | } 266 | } 267 | } 268 | 269 | public static void writeFile(InputStream inputStream, String filePath) throws IOException { 270 | File f = new File(filePath); 271 | OutputStream os = null; 272 | try { 273 | os = new FileOutputStream(f); 274 | write(inputStream, os); 275 | } finally { 276 | if (os != null) { 277 | os.flush(); 278 | os.close(); 279 | } 280 | } 281 | } 282 | 283 | private static void write(InputStream inputStream, OutputStream os) throws IOException { 284 | byte[] buf = new byte[BUFFER_LENGTH]; 285 | int len; 286 | while ((len = inputStream.read(buf)) > 0) { 287 | os.write(buf, 0, len); 288 | } 289 | } 290 | 291 | } 292 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/ui/IntelliVaultSettingsForm.form: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/ui/IntelliVaultSettings.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.ui; 2 | 3 | import com.intellij.openapi.components.ServiceManager; 4 | import com.intellij.openapi.diagnostic.Logger; 5 | import com.intellij.openapi.options.Configurable; 6 | import com.intellij.openapi.options.ConfigurationException; 7 | import com.intellij.openapi.ui.Messages; 8 | import com.razorfish.platforms.intellivault.config.IntelliVaultCRXRepository; 9 | import com.razorfish.platforms.intellivault.config.IntelliVaultConfigDefaults; 10 | import com.razorfish.platforms.intellivault.config.IntelliVaultPreferences; 11 | import com.razorfish.platforms.intellivault.services.VaultInvokerService; 12 | import com.razorfish.platforms.intellivault.services.impl.IntelliVaultPreferencesService; 13 | import org.jetbrains.annotations.Nls; 14 | import org.jetbrains.annotations.Nullable; 15 | 16 | import javax.swing.*; 17 | import java.awt.event.ActionEvent; 18 | import java.awt.event.ActionListener; 19 | import java.util.Arrays; 20 | import java.util.List; 21 | 22 | /** 23 | * Created with IntelliJ IDEA. 24 | * User: sean.steimer 25 | * Date: 3/15/13 26 | * Time: 12:41 PM 27 | * To change this template use File | Settings | File Templates. 28 | */ 29 | public class IntelliVaultSettings implements Configurable { 30 | 31 | private static final Logger log = Logger.getInstance(IntelliVaultSettings.class); 32 | 33 | public static final String FILE_IGNORE_PATTERN_SEPERATOR = ","; 34 | public static final String CURRENT_DIRECTORY_SYMBOL = "."; 35 | private JPanel jPanel; 36 | private JComboBox comboProfileSelect; 37 | private JTextField txtVaultDir; 38 | private JButton btnVaultDirBrowse; 39 | private JButton btnTempDirBrowse; 40 | private JTextField txtTempDir; 41 | private JCheckBox verboseOutputCheckBox; 42 | private JTextField txtRepoUrl; 43 | private JTextField txtUsername; 44 | private JTextField txtPassword; 45 | private JTextField txtIgnorePatterns; 46 | private JTextField txtJCRRootDirName; 47 | private JButton btnRestoreDefaults; 48 | private JCheckBox showDialogsCheckBox; 49 | private JButton btnDeleteRepository; 50 | private JButton btnSaveRepository; 51 | private JTextField txtRepoName; 52 | 53 | private IntelliVaultPreferences userPreferences; 54 | private String lastLoadedRepo = null; 55 | 56 | @Nls 57 | @Override 58 | public String getDisplayName() { 59 | return "IntelliVault"; 60 | } 61 | 62 | @Nullable 63 | @Override 64 | public String getHelpTopic() { 65 | return "IntelliVault.Plugin.Help"; 66 | } 67 | 68 | @Nullable 69 | @Override 70 | public JComponent createComponent() { 71 | IntelliVaultPreferencesService preferencesService = ServiceManager.getService(IntelliVaultPreferencesService.class); 72 | userPreferences = preferencesService.getPreferences(); 73 | 74 | btnTempDirBrowse.addActionListener(new ActionListener() { 75 | @Override 76 | public void actionPerformed(ActionEvent e) { 77 | JFileChooser chooser = new JFileChooser(); 78 | String currentDirectory = txtTempDir.getText() != null && txtTempDir.getText().length() > 0 ? 79 | txtTempDir.getText() : CURRENT_DIRECTORY_SYMBOL; 80 | chooser.setCurrentDirectory(new java.io.File(currentDirectory)); 81 | chooser.setDialogTitle("Select Temp Directory"); 82 | chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 83 | chooser.setAcceptAllFileFilterUsed(false); 84 | 85 | // Demonstrate "Open" dialog: 86 | int rVal = chooser.showOpenDialog(jPanel); 87 | if (rVal == JFileChooser.APPROVE_OPTION) { 88 | txtTempDir.setText(chooser.getSelectedFile().getAbsolutePath()); 89 | } 90 | } 91 | }); 92 | 93 | btnVaultDirBrowse.addActionListener(new ActionListener() { 94 | @Override 95 | public void actionPerformed(ActionEvent e) { 96 | JFileChooser chooser = new JFileChooser(); 97 | String curDir = txtVaultDir.getText() != null && txtVaultDir.getText().length() > 0 98 | ? txtVaultDir.getText() : CURRENT_DIRECTORY_SYMBOL; 99 | chooser.setCurrentDirectory(new java.io.File(curDir)); 100 | chooser.setDialogTitle("Select Vault Directory"); 101 | chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 102 | chooser.setAcceptAllFileFilterUsed(false); 103 | 104 | // Demonstrate "Open" dialog: 105 | int rVal = chooser.showOpenDialog(jPanel); 106 | if (rVal == JFileChooser.APPROVE_OPTION) { 107 | txtVaultDir.setText(chooser.getSelectedFile().getAbsolutePath()); 108 | } 109 | } 110 | }); 111 | 112 | btnDeleteRepository.addActionListener(new ActionListener() { 113 | @Override 114 | public void actionPerformed(ActionEvent e) { 115 | deleteCurrentlySelectedRepository(); 116 | } 117 | }); 118 | btnSaveRepository.addActionListener(new ActionListener() { 119 | @Override 120 | public void actionPerformed(ActionEvent e) { 121 | saveCurrentRepository(); 122 | } 123 | }); 124 | comboProfileSelect.addActionListener(new ActionListener() { 125 | @Override 126 | public void actionPerformed(ActionEvent e) { 127 | loadSelectedRepository(); 128 | } 129 | }); 130 | 131 | return jPanel; 132 | } 133 | 134 | @Override 135 | public boolean isModified() { 136 | return true; 137 | } 138 | 139 | @Override 140 | public void apply() throws ConfigurationException { 141 | save(); 142 | } 143 | 144 | @Override 145 | public void reset() { 146 | setDialogStateFromPreferences(userPreferences); 147 | } 148 | 149 | /** 150 | * Saves the {@link IntelliVaultPreferences} back to the {@link IntelliVaultPreferencesService} 151 | */ 152 | private void save() { 153 | saveCurrentRepository(); 154 | 155 | IntelliVaultPreferencesService preferencesService = ServiceManager.getService(IntelliVaultPreferencesService.class); 156 | injectPreferencesFromDialogState(userPreferences); 157 | preferencesService.setPreferences(userPreferences); 158 | 159 | VaultInvokerService vltInvoker = ServiceManager.getService(VaultInvokerService.class); 160 | vltInvoker.forceReInit(); 161 | } 162 | 163 | /** 164 | * Serialize the current dialog state to a {@link IntelliVaultPreferences} object which can be used by IntelliVault. 165 | * Injects non-repository preferences only, repository settings are handled outside of this. 166 | * 167 | * @param preferencesBean The bean to inject the dialog state into. 168 | */ 169 | private void injectPreferencesFromDialogState(IntelliVaultPreferences preferencesBean) { 170 | preferencesBean.vaultPath = txtVaultDir.getText(); 171 | preferencesBean.tempDirectory = txtTempDir.getText(); 172 | preferencesBean.rootFolderName = txtJCRRootDirName.getText(); 173 | 174 | preferencesBean.verbose = verboseOutputCheckBox.isSelected(); 175 | preferencesBean.showDialogs = showDialogsCheckBox.isSelected(); 176 | 177 | String ignorePatterns = txtIgnorePatterns.getText(); 178 | if (ignorePatterns != null) { 179 | String[] ignorePatternsArray = ignorePatterns.split(FILE_IGNORE_PATTERN_SEPERATOR); 180 | preferencesBean.fileIgnorePatterns = Arrays.asList(ignorePatternsArray); 181 | } 182 | 183 | } 184 | 185 | /** 186 | * Removes the currently selected {@link IntelliVaultCRXRepository} from the current {@link IntelliVaultPreferences} state. 187 | */ 188 | private void deleteCurrentlySelectedRepository() { 189 | Object selectedItem = comboProfileSelect.getSelectedItem(); 190 | if (selectedItem != null) { 191 | int deleteChoice = Messages.showYesNoDialog("Are you sure you want to delete the repository configuration '" + selectedItem.toString() + "'?", "Delete Configuration", null); 192 | if (deleteChoice == Messages.YES) { 193 | comboProfileSelect.removeItem(selectedItem); 194 | userPreferences.removeRepositoryConfiguration(((IntelliVaultCRXRepository) selectedItem).getName()); 195 | } 196 | } else { 197 | log.warn("No option selected"); 198 | } 199 | } 200 | 201 | /** 202 | * Puts the current {@link IntelliVaultCRXRepository} state in the {@link IntelliVaultPreferences} repository list. 203 | */ 204 | private void saveCurrentRepository() { 205 | String repoName = txtRepoName.getText(); 206 | 207 | // Setup the new repository. 208 | IntelliVaultCRXRepository newRepo = new IntelliVaultCRXRepository( 209 | repoName, 210 | txtRepoUrl.getText(), 211 | txtUsername.getText(), 212 | txtPassword.getText() 213 | ); 214 | 215 | // Check if this put request is replacing an old repository configuration. 216 | IntelliVaultCRXRepository oldRepo = null; 217 | if (!repoName.equals(lastLoadedRepo) && lastLoadedRepo != null) { 218 | oldRepo = userPreferences.getRepositoryConfiguration(lastLoadedRepo); 219 | } 220 | 221 | if (oldRepo != null) { 222 | // Repo name has changed, replace in the same slot. 223 | oldRepo.replaceWith(newRepo); 224 | lastLoadedRepo = repoName; 225 | } else { 226 | // Repo name didn't change 227 | // This creates a new or overwrites an old. The above steps ensure renaming happens properly. 228 | newRepo = userPreferences.putRepositoryConfiguration( 229 | repoName, 230 | txtRepoUrl.getText(), 231 | txtUsername.getText(), 232 | txtPassword.getText() 233 | ); 234 | } 235 | 236 | rebuildRepositoryComboBox(newRepo); 237 | } 238 | 239 | /** 240 | * Sets the dialog state to reflect the newly selected {@link IntelliVaultCRXRepository} 241 | * If the user chooses the "Create New Repository..." option a new repository will be added to the {@link IntelliVaultPreferences} state. 242 | */ 243 | private void loadSelectedRepository() { 244 | Object selectedItem = comboProfileSelect.getSelectedItem(); 245 | if (selectedItem != null) { 246 | if (selectedItem instanceof IntelliVaultCRXRepository) { 247 | setDialogStateFromRepository((IntelliVaultCRXRepository) selectedItem); 248 | lastLoadedRepo = ((IntelliVaultCRXRepository) selectedItem).getName(); 249 | } else { 250 | // New repo was selected 251 | IntelliVaultCRXRepository repo = new IntelliVaultCRXRepository(); 252 | setDialogStateFromRepository(repo); 253 | lastLoadedRepo = null; 254 | } 255 | } else { 256 | log.warn("No option selected"); 257 | } 258 | } 259 | 260 | /** 261 | * De-serialize an IntelliVaultPreferences object to the dialog, setting all dialog fields as defined in the object 262 | * passed in. 263 | * 264 | * @param preferences the preferences object to set the dialog fields from. 265 | */ 266 | private void setDialogStateFromPreferences(final IntelliVaultPreferences preferences) { 267 | txtVaultDir.setText(preferences.vaultPath); 268 | txtTempDir.setText(preferences.tempDirectory); 269 | txtJCRRootDirName.setText(preferences.rootFolderName); 270 | 271 | verboseOutputCheckBox.setSelected(preferences.verbose); 272 | showDialogsCheckBox.setSelected(preferences.showDialogs); 273 | 274 | StringBuilder buf = new StringBuilder(); 275 | for (String s : preferences.fileIgnorePatterns) { 276 | buf.append(s).append(FILE_IGNORE_PATTERN_SEPERATOR); 277 | } 278 | String ignorePatterns = buf.toString(); 279 | ignorePatterns = ignorePatterns.substring(0, ignorePatterns.length() - 1); 280 | txtIgnorePatterns.setText(ignorePatterns); 281 | 282 | rebuildRepositoryComboBox(null); 283 | } 284 | 285 | /** 286 | * Sets the dialog state to represent a {@link IntelliVaultCRXRepository}. 287 | * 288 | * @param repository The {@link IntelliVaultCRXRepository} to update the ui values with. 289 | */ 290 | private void setDialogStateFromRepository(IntelliVaultCRXRepository repository) { 291 | if (repository != null) { 292 | txtRepoName.setText(repository.getName()); 293 | txtRepoUrl.setText(repository.getRepoUrl()); 294 | txtPassword.setText(repository.getPassword()); 295 | txtUsername.setText(repository.getUsername()); 296 | } else { 297 | txtRepoName.setText(IntelliVaultConfigDefaults.REPO_NAME); 298 | txtRepoUrl.setText(IntelliVaultConfigDefaults.REPO_URL); 299 | txtPassword.setText(IntelliVaultConfigDefaults.REPO_PASSWORD); 300 | txtUsername.setText(IntelliVaultConfigDefaults.REPO_USER); 301 | } 302 | } 303 | 304 | /** 305 | * Rebuilds the combo box that represents the current {@link IntelliVaultPreferences} state's {@link IntelliVaultCRXRepository} list. 306 | * 307 | * @param selectedItem An optional item to set as the selected item after rebuild. 308 | */ 309 | private void rebuildRepositoryComboBox(IntelliVaultCRXRepository selectedItem) { 310 | comboProfileSelect.removeAllItems(); 311 | comboProfileSelect.addItem("Create New Repository..."); 312 | List rValues = userPreferences.getRepoConfigList(); 313 | for (IntelliVaultCRXRepository repo : rValues) { 314 | comboProfileSelect.addItem(repo); 315 | } 316 | if (selectedItem == null) { 317 | selectedItem = userPreferences.getFirstRepositoryConfiguration(); 318 | } 319 | if (selectedItem != null) { 320 | comboProfileSelect.setSelectedItem(selectedItem); 321 | } 322 | setDialogStateFromRepository(selectedItem); 323 | } 324 | 325 | @Override 326 | public void disposeUIResources() { 327 | //To change body of implemented methods use File | Settings | File Templates. 328 | } 329 | 330 | } 331 | -------------------------------------------------------------------------------- /src/com/razorfish/platforms/intellivault/services/impl/IntelliVaultServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.razorfish.platforms.intellivault.services.impl; 2 | 3 | import com.intellij.execution.ui.ConsoleView; 4 | import com.intellij.execution.ui.ConsoleViewContentType; 5 | import com.intellij.openapi.application.ApplicationManager; 6 | import com.intellij.openapi.components.ServiceManager; 7 | import com.intellij.openapi.diagnostic.Logger; 8 | import com.intellij.openapi.progress.ProgressIndicator; 9 | import com.intellij.openapi.ui.Messages; 10 | import com.razorfish.platforms.intellivault.actions.VaultOperationDirectory; 11 | import com.razorfish.platforms.intellivault.config.IntelliVaultCRXRepository; 12 | import com.razorfish.platforms.intellivault.config.IntelliVaultOperationConfig; 13 | import com.razorfish.platforms.intellivault.exceptions.IntelliVaultException; 14 | import com.razorfish.platforms.intellivault.filter.VaultImportFilter; 15 | import com.razorfish.platforms.intellivault.services.IntelliVaultService; 16 | import com.razorfish.platforms.intellivault.services.VaultInvokerService; 17 | import com.razorfish.platforms.intellivault.utils.FileUtils; 18 | import com.razorfish.platforms.intellivault.utils.IntelliVaultConstants; 19 | 20 | import java.io.BufferedReader; 21 | import java.io.File; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.io.InputStreamReader; 25 | import java.io.OutputStream; 26 | import java.io.PipedInputStream; 27 | import java.io.PipedOutputStream; 28 | import java.io.PrintStream; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | 32 | /** 33 | * The IntelliVault service handles all of the logic around calling vault such as copying files, setting up vault 34 | * configurations, etc. 35 | */ 36 | public class IntelliVaultServiceImpl implements IntelliVaultService { 37 | 38 | public static final String CHECKOUT = "co"; 39 | public static final String DEBUG = "debug"; 40 | public static final String FILTER = "--filter"; 41 | public static final String CREDENTIALS = "--credentials"; 42 | public static final String VERBOSE = "--verbose"; 43 | public static final String FORCE = "--force"; 44 | public static final String LOG_LEVEL = "--log-level"; 45 | public static final String WORKSPACE_ROOT_PATH = "/crx/server"; 46 | public static final String CREDENTIALS_SEPERATOR = ":"; 47 | public static final String NEW_LINE_CHAR = "\n"; 48 | private static final String IMPORT = "import"; 49 | private static final String EXPORT = "export"; 50 | 51 | private static final Logger log = Logger.getInstance(IntelliVaultServiceImpl.class); 52 | // private PrintStream sysOut; 53 | private OutputStream logOut; 54 | // private File logFile; 55 | private boolean isError; 56 | private String errorMsg; 57 | 58 | @Override 59 | public void vaultExport(final IntelliVaultCRXRepository repository, final IntelliVaultOperationConfig opConf, 60 | final VaultOperationDirectory exportOpDir, final ProgressIndicator progressIndicator, ConsoleView console) 61 | throws IntelliVaultException { 62 | progressIndicator.setText2("Preparing export"); 63 | 64 | isError = false; 65 | errorMsg = null; 66 | 67 | final File exportBaseDir = FileUtils.createTempDirectory(opConf.getTempDirectory()); 68 | 69 | try { 70 | final List jcrPaths = new ArrayList(); 71 | jcrPaths.add(exportOpDir.getJcrPath()); 72 | File filterFile = createFilterFile(exportBaseDir, jcrPaths); 73 | 74 | progressIndicator.setText2("Running VLT Export"); 75 | final String[] args = prepareExportArgsList(repository, opConf, exportBaseDir, filterFile); 76 | 77 | progressIndicator.startNonCancelableSection(); 78 | invokeVault(opConf, args, console); 79 | progressIndicator.finishNonCancelableSection(); 80 | 81 | progressIndicator.setText2("Copying export contents to IDEA"); 82 | 83 | ApplicationManager.getApplication().invokeAndWait(() -> { 84 | try { 85 | FileUtils.copyExportContents(exportOpDir.getPsiDir(), exportBaseDir, exportOpDir.getJcrPath()); 86 | } catch (IntelliVaultException e) { 87 | // TODO work on this 88 | log.error("Error copying contents.", e); 89 | Messages.showErrorDialog(e.getLocalizedMessage(), "IntelliVault Error!"); 90 | } 91 | }); 92 | 93 | } finally { 94 | if (!opConf.isDebug()) { 95 | try { 96 | FileUtils.deleteDirectoryRecursive(exportBaseDir); 97 | } catch (IOException e) { 98 | throw new IntelliVaultException("Error while deleting temp contents.", e); 99 | } 100 | } 101 | } 102 | 103 | } 104 | 105 | @Override 106 | public void vaultImport(final IntelliVaultCRXRepository repository, final IntelliVaultOperationConfig opConf, 107 | final VaultOperationDirectory importOpDir, ProgressIndicator progressIndicator, ConsoleView console) 108 | throws IntelliVaultException { 109 | progressIndicator.setText2("Preparing import"); 110 | 111 | isError = false; 112 | errorMsg = null; 113 | 114 | final File importBaseDir = FileUtils.createTempDirectory(opConf.getTempDirectory()); 115 | 116 | try { 117 | final List jcrPaths = new ArrayList<>(); 118 | jcrPaths.add(importOpDir.getJcrPath()); 119 | File filterFile = createFilterFile(importBaseDir, jcrPaths); 120 | 121 | try { 122 | FileUtils.writeFile("com/razorfish/platforms/intellivault/settings.xml", 123 | filterFile.getParentFile().getAbsoluteFile() + File.separator + "settings.xml"); 124 | FileUtils.writeFile("com/razorfish/platforms/intellivault/config.xml", 125 | filterFile.getParentFile().getAbsoluteFile() + File.separator + "config.xml"); 126 | } catch (IOException e) { 127 | throw new IntelliVaultException("Error creating import config files.", e); 128 | } 129 | 130 | progressIndicator.setText2("Copying import contents to Temp Directory"); 131 | FileUtils.copyImportContents(importBaseDir, importOpDir.getPsiDir(), importOpDir.getJcrPath(), 132 | new VaultImportFilter(opConf.getFileIgnorePatterns())); 133 | 134 | progressIndicator.setText2("Running VLT Import"); 135 | String[] args = prepareImportArgsList(repository, opConf, importBaseDir); 136 | 137 | progressIndicator.startNonCancelableSection(); 138 | invokeVault(opConf, args, console); 139 | progressIndicator.finishNonCancelableSection(); 140 | } finally { 141 | if (!opConf.isDebug()) { 142 | try { 143 | FileUtils.deleteDirectoryRecursive(importBaseDir); 144 | } catch (IOException e) { 145 | throw new IntelliVaultException("Error while deleting temp contents.", e); 146 | } 147 | } 148 | } 149 | 150 | } 151 | 152 | private void invokeVault(final IntelliVaultOperationConfig opConf, final String[] args, ConsoleView console) 153 | throws IntelliVaultException { 154 | PrintStream sysOut = null; 155 | try { 156 | sysOut = redirectSysOut(console); 157 | } catch (IOException e) { 158 | log.error("Error redirecting sysout, ignore.", e); 159 | // do nothing, just let it go to sys out 160 | } 161 | 162 | VaultInvokerService vlt = ServiceManager.getService(VaultInvokerService.class); 163 | vlt.invokeVault(opConf.getVaultPath(), args); 164 | 165 | try { 166 | restoreSysOut(sysOut); 167 | } catch (IOException e) { 168 | log.error("Error restoring sysout, ignore.", e); 169 | // do nothing, just let it go to sys out 170 | } 171 | 172 | if (isError) { 173 | throw new IntelliVaultException(errorMsg); 174 | } 175 | } 176 | 177 | private String[] prepareImportArgsList(final IntelliVaultCRXRepository repository, 178 | final IntelliVaultOperationConfig opConf, final File importBaseDir) { 179 | List argsList = new ArrayList(); 180 | 181 | if (opConf.isDebug()) { 182 | argsList.add(LOG_LEVEL); 183 | argsList.add(DEBUG); 184 | } 185 | 186 | argsList.add(IMPORT); 187 | 188 | argsList.add(repository.getRepoUrl()); 189 | 190 | argsList.add(importBaseDir.getAbsolutePath()); 191 | 192 | argsList.add(IntelliVaultConstants.JCR_PATH_SEPERATOR); 193 | 194 | argsList.add(CREDENTIALS); 195 | argsList.add(repository.getUsername() + CREDENTIALS_SEPERATOR + repository.getPassword()); 196 | 197 | if (opConf.isVerbose()) { 198 | argsList.add(VERBOSE); 199 | } 200 | 201 | return argsList.toArray(new String[argsList.size()]); 202 | } 203 | 204 | private String[] prepareExportArgsList(final IntelliVaultCRXRepository repository, 205 | final IntelliVaultOperationConfig opConf, final File exportBaseDir, final File filterFile) { 206 | List argsList = new ArrayList(); 207 | 208 | if (opConf.isDebug()) { 209 | argsList.add(LOG_LEVEL); 210 | argsList.add(DEBUG); 211 | } 212 | 213 | argsList.add(CHECKOUT); 214 | 215 | argsList.add(FILTER); 216 | argsList.add(filterFile.getAbsolutePath()); 217 | 218 | argsList.add(repository.getRepoUrl() + WORKSPACE_ROOT_PATH); 219 | 220 | argsList.add(exportBaseDir.getAbsolutePath()); 221 | 222 | argsList.add(CREDENTIALS); 223 | argsList.add(repository.getUsername() + CREDENTIALS_SEPERATOR + repository.getPassword()); 224 | 225 | if (opConf.isVerbose()) { 226 | argsList.add(VERBOSE); 227 | } 228 | 229 | return argsList.toArray(new String[argsList.size()]); 230 | } 231 | 232 | /** 233 | * Create filter.xml file and populate it's content from the list of jcr paths handled by this operation. 234 | * 235 | * @param baseDir the base directory for the vault operation (export or import) 236 | * @param paths the List of jcr paths to be handled by the operation 237 | * @return File representing the filter.xml that was created 238 | * @throws IntelliVaultException if an error occurs preventing creation of the file 239 | */ 240 | private File createFilterFile(final File baseDir, final List paths) throws IntelliVaultException { 241 | File filterFile = null; 242 | FileOutputStream os = null; 243 | try { 244 | filterFile = createFilterFile(baseDir); 245 | os = new FileOutputStream(filterFile); 246 | os.write(("\n" + "\n") 247 | .getBytes("UTF-8")); 248 | for (String path : paths) { 249 | os.write(("\t\n").getBytes("UTF-8")); 250 | } 251 | 252 | os.write(("").getBytes()); 253 | } catch (IOException e) { 254 | throw new IntelliVaultException(e); 255 | } finally { 256 | if (os != null) { 257 | try { 258 | os.flush(); 259 | os.close(); 260 | } catch (IOException e) { 261 | throw new IntelliVaultException(e); 262 | } 263 | } 264 | } 265 | 266 | return filterFile; 267 | } 268 | 269 | /** 270 | * Create an empty filter.xml file. 271 | * 272 | * @param baseDir the base directory for the vault operation (export or import) 273 | * @return File representing the filter.xml that was created 274 | * @throws IOException if an IOError occurs preventing creation of the file 275 | */ 276 | private File createFilterFile(File baseDir) throws IOException { 277 | File filterConfigDir = 278 | new File(baseDir.getAbsolutePath() + File.separator + "META-INF" + File.separator + "vault"); 279 | filterConfigDir.mkdirs(); 280 | 281 | File filterFile = new File(filterConfigDir.getAbsolutePath() + File.separator + "filter.xml"); 282 | 283 | if (!filterFile.exists()) { 284 | filterFile.createNewFile(); 285 | } 286 | 287 | return filterFile; 288 | } 289 | 290 | /** 291 | * Redirect the system output for vault to another, custom output stream. Also starts a thread to read that stream 292 | * to identify underlying vault errors. 293 | * 294 | * @param console the console to log messages to 295 | * @return PrintStream that formerly was System.out, so that it can be restored later 296 | * @throws IOException if an error occurs 297 | */ 298 | private PrintStream redirectSysOut(final ConsoleView console) throws IOException { 299 | PrintStream sysOut = System.out; 300 | 301 | final PipedInputStream in = new PipedInputStream(); 302 | // TODO close logOut 303 | logOut = new PipedOutputStream(in); 304 | 305 | System.setOut(new PrintStream(logOut)); 306 | 307 | final Thread writerThread = new Thread() { 308 | 309 | public void run() { 310 | log.debug("Starting input listener"); 311 | try { 312 | BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); 313 | for (String line = reader.readLine(); line != null; line = reader.readLine()) { 314 | if (line.contains("[ERROR]") || (isError && (line.contains("caused by") || line 315 | .contains("at")))) { 316 | isError = true; 317 | errorMsg += NEW_LINE_CHAR + line; 318 | 319 | console.print(line + NEW_LINE_CHAR, ConsoleViewContentType.ERROR_OUTPUT); 320 | log.error(line); 321 | } else { 322 | console.print(line + NEW_LINE_CHAR, ConsoleViewContentType.NORMAL_OUTPUT); 323 | log.info(line); 324 | } 325 | 326 | } 327 | } catch (IOException e) { 328 | log.error("Exception reading output stream", e); 329 | } 330 | log.debug("Input reader closing"); 331 | } 332 | 333 | }; 334 | writerThread.start(); 335 | 336 | return sysOut; 337 | } 338 | 339 | /** 340 | * Restore the system output stream 341 | * 342 | * @param sysOut the output stream to restore to System.out 343 | * @throws IOException if an error occurs while restoring 344 | */ 345 | private void restoreSysOut(PrintStream sysOut) throws IOException { 346 | System.setOut(sysOut); 347 | 348 | logOut.flush(); 349 | logOut.close(); 350 | } 351 | } 352 | --------------------------------------------------------------------------------