be41c81a5077797afabd1044b7bc7a5a4591bdcd
[idea/community.git] / plugins / devkit / src / build / PluginBuildConfiguration.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.jetbrains.idea.devkit.build;
17
18 import com.intellij.openapi.application.AccessToken;
19 import com.intellij.openapi.application.ReadAction;
20 import com.intellij.openapi.application.Result;
21 import com.intellij.openapi.application.WriteAction;
22 import com.intellij.openapi.components.PersistentStateComponent;
23 import com.intellij.openapi.components.State;
24 import com.intellij.openapi.components.Storage;
25 import com.intellij.openapi.components.StoragePathMacros;
26 import com.intellij.openapi.module.Module;
27 import com.intellij.openapi.module.ModuleServiceManager;
28 import com.intellij.openapi.module.ModuleType;
29 import com.intellij.openapi.ui.Messages;
30 import com.intellij.openapi.util.Disposer;
31 import com.intellij.openapi.util.io.FileUtil;
32 import com.intellij.openapi.util.text.StringUtil;
33 import com.intellij.openapi.vfs.LocalFileSystem;
34 import com.intellij.openapi.vfs.VfsUtilCore;
35 import com.intellij.openapi.vfs.VirtualFile;
36 import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
37 import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
38 import com.intellij.util.descriptors.ConfigFile;
39 import com.intellij.util.descriptors.ConfigFileContainer;
40 import com.intellij.util.descriptors.ConfigFileFactory;
41 import com.intellij.util.descriptors.ConfigFileInfo;
42 import com.intellij.util.xmlb.annotations.Attribute;
43 import org.jetbrains.annotations.NonNls;
44 import org.jetbrains.annotations.NotNull;
45 import org.jetbrains.annotations.Nullable;
46 import org.jetbrains.annotations.TestOnly;
47 import org.jetbrains.idea.devkit.DevKitBundle;
48 import org.jetbrains.idea.devkit.module.PluginDescriptorConstants;
49 import org.jetbrains.idea.devkit.module.PluginModuleType;
50
51 import java.io.File;
52
53 @State(name = "DevKit.ModuleBuildProperties", storages = @Storage(StoragePathMacros.MODULE_FILE))
54 public class PluginBuildConfiguration implements PersistentStateComponent<PluginBuildConfiguration.State> {
55   private final Module myModule;
56   private final ConfigFileContainer myPluginXmlContainer;
57   private VirtualFilePointer myManifestFilePointer;
58   private boolean myUseUserManifest = false;
59   @NonNls private static final String META_INF = "META-INF";
60   @NonNls private static final String PLUGIN_XML = "plugin.xml";
61
62   private State state = new State();
63
64   public PluginBuildConfiguration(@NotNull Module module) {
65     myModule = module;
66     myPluginXmlContainer = ConfigFileFactory.getInstance().createSingleFileContainer(myModule.getProject(), PluginDescriptorConstants.META_DATA);
67     Disposer.register(module, myPluginXmlContainer);
68   }
69
70   @Nullable
71   public static PluginBuildConfiguration getInstance(@NotNull Module module) {
72     return ModuleType.is(module, PluginModuleType.getInstance()) ? ModuleServiceManager.getService(module, PluginBuildConfiguration.class) : null;
73   }
74
75   static class State {
76     @Attribute
77     String url;
78
79     @Attribute
80     String manifest;
81
82     @Override
83     public boolean equals(Object o) {
84       if (this == o) return true;
85       if (o == null || getClass() != o.getClass()) return false;
86
87       State state = (State)o;
88
89       if (url != null ? !url.equals(state.url) : state.url != null) return false;
90       if (manifest != null ? !manifest.equals(state.manifest) : state.manifest != null) return false;
91
92       return true;
93     }
94
95     @Override
96     public int hashCode() {
97       int result = url != null ? url.hashCode() : 0;
98       result = 31 * result + (manifest != null ? manifest.hashCode() : 0);
99       return result;
100     }
101   }
102
103   @Nullable
104   @Override
105   public State getState() {
106     state.url = getPluginXmlUrl();
107     state.manifest = myManifestFilePointer == null ? null : myManifestFilePointer.getUrl();
108     return state;
109   }
110
111   @Override
112   public void loadState(State state) {
113     this.state = state;
114     if (state.url != null) {
115       myPluginXmlContainer.getConfiguration().replaceConfigFile(PluginDescriptorConstants.META_DATA, state.url);
116     }
117     if (state.manifest != null) {
118       setManifestPath(VfsUtilCore.urlToPath(state.manifest));
119     }
120   }
121
122   @Nullable
123   public ConfigFile getPluginXML() {
124     return myPluginXmlContainer.getConfigFile(PluginDescriptorConstants.META_DATA);
125   }
126
127   @TestOnly
128   public void setPluginXmlFromVirtualFile(VirtualFile virtualFile) {
129     myPluginXmlContainer.getConfiguration().replaceConfigFile(PluginDescriptorConstants.META_DATA, virtualFile.getUrl());
130   }
131
132   private void createDescriptor(final String url) {
133     final ConfigFileInfo descriptor = new ConfigFileInfo(PluginDescriptorConstants.META_DATA, url);
134     myPluginXmlContainer.getConfiguration().addConfigFile(descriptor);
135     ConfigFileFactory.getInstance().createFile(myModule.getProject(), descriptor.getUrl(), PluginDescriptorConstants.META_DATA.getDefaultVersion(),
136                                                false);
137   }
138
139   @Nullable
140   public ConfigFile getPluginXmlConfigFile() {
141     return myPluginXmlContainer.getConfigFile(PluginDescriptorConstants.META_DATA);
142   }
143
144   @Nullable
145   private String getPluginXmlUrl() {
146     ConfigFile configFile = getPluginXmlConfigFile();
147     return configFile != null ? configFile.getUrl() : null;
148   }
149
150   private String getDefaultLocation() {
151     return new File(myModule.getModuleFilePath()).getParent() + File.separator + META_INF + File.separator + PLUGIN_XML;
152   }
153
154   @NotNull
155   public String getPluginXmlPath() {
156     String url = getPluginXmlUrl();
157     if (url == null) {
158       return getDefaultLocation();
159     }
160     return FileUtil.toSystemDependentName(VfsUtilCore.urlToPath(url));
161   }
162
163   public void setPluginXmlPathAndCreateDescriptorIfDoesntExist(final String pluginXmlPath) {
164     myPluginXmlContainer.getConfiguration().removeConfigFiles(PluginDescriptorConstants.META_DATA);
165     new WriteAction() {
166       @Override
167       protected void run(@NotNull final Result result) throws Throwable {
168         createDescriptor(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(pluginXmlPath)));
169       }
170     }.execute();
171   }
172
173   public void setManifestPath(@Nullable String manifestPath) {
174     if (StringUtil.isEmpty(manifestPath)) {
175       myManifestFilePointer = null;
176       return;
177     }
178
179     VirtualFile manifest = LocalFileSystem.getInstance().findFileByPath(manifestPath);
180     if (manifest == null) {
181       Messages.showErrorDialog(myModule.getProject(), DevKitBundle.message("error.file.not.found.message", manifestPath), DevKitBundle.message("error.file.not.found"));
182       AccessToken token = ReadAction.start();
183       try {
184         myManifestFilePointer = VirtualFilePointerManager.getInstance().create(
185           VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(manifestPath)), myModule, null);
186       }
187       finally {
188         token.finish();
189       }
190     }
191     else {
192       AccessToken token = ReadAction.start();
193       try {
194         myManifestFilePointer = VirtualFilePointerManager.getInstance().create(manifest, myModule, null);
195       }
196       finally {
197         token.finish();
198       }
199     }
200   }
201
202   @Nullable
203   public String getManifestPath() {
204     return myManifestFilePointer != null ? FileUtil.toSystemDependentName(myManifestFilePointer.getPresentableUrl()) : null;
205   }
206
207   @Nullable
208   public VirtualFile getManifest(){
209     return myManifestFilePointer != null ? myManifestFilePointer.getFile() : null;
210   }
211
212   public boolean isUseUserManifest() {
213     return myUseUserManifest;
214   }
215
216   public void setUseUserManifest(final boolean useUserManifest) {
217     myUseUserManifest = useUserManifest;
218   }
219 }