2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com
.intellij
.packaging
.impl
.elements
;
18 import com
.intellij
.openapi
.extensions
.Extensions
;
19 import com
.intellij
.openapi
.module
.Module
;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.openapi
.roots
.OrderRootType
;
22 import com
.intellij
.openapi
.roots
.impl
.libraries
.LibraryImpl
;
23 import com
.intellij
.openapi
.roots
.impl
.libraries
.LibraryTableImplUtil
;
24 import com
.intellij
.openapi
.roots
.libraries
.Library
;
25 import com
.intellij
.openapi
.roots
.libraries
.LibraryTable
;
26 import com
.intellij
.openapi
.util
.io
.FileUtil
;
27 import com
.intellij
.openapi
.util
.text
.StringUtil
;
28 import com
.intellij
.openapi
.vfs
.VirtualFile
;
29 import com
.intellij
.packaging
.artifacts
.Artifact
;
30 import com
.intellij
.packaging
.artifacts
.ArtifactPointerManager
;
31 import com
.intellij
.packaging
.elements
.*;
32 import com
.intellij
.packaging
.ui
.ArtifactEditorContext
;
33 import com
.intellij
.util
.ArrayUtil
;
34 import com
.intellij
.util
.PathUtil
;
35 import org
.jetbrains
.annotations
.NonNls
;
36 import org
.jetbrains
.annotations
.NotNull
;
37 import org
.jetbrains
.annotations
.Nullable
;
39 import java
.util
.ArrayList
;
40 import java
.util
.Collections
;
41 import java
.util
.List
;
46 public class PackagingElementFactoryImpl
extends PackagingElementFactory
{
47 public static final PackagingElementType
<DirectoryPackagingElement
> DIRECTORY_ELEMENT_TYPE
= new DirectoryElementType();
48 public static final PackagingElementType
<ArchivePackagingElement
> ARCHIVE_ELEMENT_TYPE
= new ArchiveElementType();
49 public static final PackagingElementType
<FileCopyPackagingElement
> FILE_COPY_ELEMENT_TYPE
= new FileCopyElementType();
50 public static final PackagingElementType
<DirectoryCopyPackagingElement
> DIRECTORY_COPY_ELEMENT_TYPE
= new DirectoryCopyElementType();
51 public static final PackagingElementType
<ArtifactRootElement
<?
>> ARTIFACT_ROOT_ELEMENT_TYPE
= new ArtifactRootElementType();
52 private static final PackagingElementType
[] STANDARD_TYPES
= {
53 DIRECTORY_ELEMENT_TYPE
, ARCHIVE_ELEMENT_TYPE
,
54 LibraryElementType
.LIBRARY_ELEMENT_TYPE
, ModuleOutputElementType
.MODULE_OUTPUT_ELEMENT_TYPE
,
55 ArtifactElementType
.ARTIFACT_ELEMENT_TYPE
, FILE_COPY_ELEMENT_TYPE
, DIRECTORY_COPY_ELEMENT_TYPE
60 public PackagingElementType
<?
>[] getNonCompositeElementTypes() {
61 final List
<PackagingElementType
> elementTypes
= new ArrayList
<PackagingElementType
>();
62 for (PackagingElementType elementType
: getAllElementTypes()) {
63 if (!(elementType
instanceof CompositePackagingElementType
)) {
64 elementTypes
.add(elementType
);
67 return elementTypes
.toArray(new PackagingElementType
[elementTypes
.size()]);
72 public ComplexPackagingElementType
<?
>[] getComplexElementTypes() {
73 List
<ComplexPackagingElementType
<?
>> types
= new ArrayList
<ComplexPackagingElementType
<?
>>();
74 for (PackagingElementType type
: getAllElementTypes()) {
75 if (type
instanceof ComplexPackagingElementType
) {
76 types
.add((ComplexPackagingElementType
)type
);
79 return types
.toArray(new ComplexPackagingElementType
[types
.size()]);
84 public CompositePackagingElementType
<?
>[] getCompositeElementTypes() {
85 final List
<CompositePackagingElementType
> elementTypes
= new ArrayList
<CompositePackagingElementType
>();
86 for (PackagingElementType elementType
: getAllElementTypes()) {
87 if (elementType
instanceof CompositePackagingElementType
) {
88 elementTypes
.add((CompositePackagingElementType
)elementType
);
91 return elementTypes
.toArray(new CompositePackagingElementType
[elementTypes
.size()]);
95 public PackagingElementType
<?
> findElementType(String id
) {
96 for (PackagingElementType elementType
: getAllElementTypes()) {
97 if (elementType
.getId().equals(id
)) {
101 if (id
.equals(ARTIFACT_ROOT_ELEMENT_TYPE
.getId())) {
102 return ARTIFACT_ROOT_ELEMENT_TYPE
;
104 throw new AssertionError(id
+ " not registered");
109 public PackagingElementType
[] getAllElementTypes() {
110 final PackagingElementType
[] types
= Extensions
.getExtensions(PackagingElementType
.EP_NAME
);
111 return ArrayUtil
.mergeArrays(STANDARD_TYPES
, types
, PackagingElementType
.class);
116 public PackagingElement
<?
> createArtifactElement(@NotNull Artifact artifact
, @NotNull Project project
) {
117 return new ArtifactPackagingElement(project
, ArtifactPointerManager
.getInstance(project
).create(artifact
));
121 public DirectoryPackagingElement
createDirectory(@NotNull @NonNls String directoryName
) {
122 return new DirectoryPackagingElement(directoryName
);
127 public ArtifactRootElement
<?
> createArtifactRootElement() {
128 return new ArtifactRootElementImpl();
133 public CompositePackagingElement
<?
> getOrCreateDirectory(@NotNull CompositePackagingElement
<?
> parent
, @NotNull String relativePath
) {
134 return getOrCreateDirectoryOrArchive(parent
, relativePath
, true);
139 public CompositePackagingElement
<?
> getOrCreateArchive(@NotNull CompositePackagingElement
<?
> parent
, @NotNull String relativePath
) {
140 return getOrCreateDirectoryOrArchive(parent
, relativePath
, false);
144 public void addFileCopy(@NotNull CompositePackagingElement
<?
> root
, @NotNull String outputDirectoryPath
, @NotNull String sourceFilePath
) {
145 addFileCopy(root
, outputDirectoryPath
, sourceFilePath
, null);
149 public void addFileCopy(@NotNull CompositePackagingElement
<?
> root
, @NotNull String outputDirectoryPath
, @NotNull String sourceFilePath
,
150 @Nullable String outputFileName
) {
151 final String fileName
= PathUtil
.getFileName(sourceFilePath
);
152 if (outputFileName
!= null && outputFileName
.equals(fileName
)) {
153 outputFileName
= null;
155 getOrCreateDirectory(root
, outputDirectoryPath
).addOrFindChild(new FileCopyPackagingElement(sourceFilePath
, outputFileName
));
159 private CompositePackagingElement
<?
> getOrCreateDirectoryOrArchive(@NotNull CompositePackagingElement
<?
> root
,
160 @NotNull @NonNls String path
, final boolean directory
) {
161 path
= StringUtil
.trimStart(StringUtil
.trimEnd(path
, "/"), "/");
162 if (path
.length() == 0) {
165 int index
= path
.lastIndexOf('/');
166 String lastName
= path
.substring(index
+ 1);
167 String parentPath
= index
!= -1 ? path
.substring(0, index
) : "";
169 final CompositePackagingElement
<?
> parent
= getOrCreateDirectoryOrArchive(root
, parentPath
, true);
170 final CompositePackagingElement
<?
> last
= directory ?
createDirectory(lastName
) : createArchive(lastName
);
171 return parent
.addOrFindChild(last
);
175 public PackagingElement
<?
> createModuleOutput(@NotNull String moduleName
, Project project
) {
176 return new ModuleOutputPackagingElement(moduleName
);
181 public PackagingElement
<?
> createModuleOutput(@NotNull Module module
) {
182 return new ModuleOutputPackagingElement(module
.getName());
187 public List
<?
extends PackagingElement
<?
>> createLibraryElements(@NotNull Library library
) {
188 final LibraryTable table
= library
.getTable();
189 final String libraryName
= library
.getName();
191 return Collections
.singletonList(createLibraryFiles(libraryName
, table
.getTableLevel(), null));
193 if (libraryName
!= null) {
194 final Module module
= ((LibraryImpl
)library
).getModule();
195 if (module
!= null) {
196 return Collections
.singletonList(createLibraryFiles(libraryName
, LibraryTableImplUtil
.MODULE_LEVEL
, module
.getName()));
199 final List
<PackagingElement
<?
>> elements
= new ArrayList
<PackagingElement
<?
>>();
200 for (VirtualFile file
: library
.getFiles(OrderRootType
.CLASSES
)) {
201 final String path
= FileUtil
.toSystemIndependentName(PathUtil
.getLocalPath(file
));
202 elements
.add(file
.isDirectory() && file
.isInLocalFileSystem() ?
new DirectoryCopyPackagingElement(path
) : new FileCopyPackagingElement(path
));
209 public PackagingElement
<?
> createLibraryFiles(@NotNull String libraryName
, @NotNull String level
, String moduleName
) {
210 return new LibraryPackagingElement(level
, libraryName
, moduleName
);
214 public CompositePackagingElement
<?
> createArchive(@NotNull @NonNls String archiveFileName
) {
215 return new ArchivePackagingElement(archiveFileName
);
219 private static PackagingElement
<?
> findArchiveOrDirectoryByName(@NotNull CompositePackagingElement
<?
> parent
, @NotNull String name
) {
220 for (PackagingElement
<?
> element
: parent
.getChildren()) {
221 if (element
instanceof ArchivePackagingElement
&& ((ArchivePackagingElement
)element
).getArchiveFileName().equals(name
) ||
222 element
instanceof DirectoryPackagingElement
&& ((DirectoryPackagingElement
)element
).getDirectoryName().equals(name
)) {
230 public static String
suggestFileName(@NotNull CompositePackagingElement
<?
> parent
, @NonNls @NotNull String prefix
, @NonNls @NotNull String suffix
) {
231 String name
= prefix
+ suffix
;
233 while (findArchiveOrDirectoryByName(parent
, name
) != null) {
234 name
= prefix
+ i
++ + suffix
;
241 public PackagingElement
<?
> createDirectoryCopyWithParentDirectories(@NotNull String filePath
, @NotNull String relativeOutputPath
) {
242 return createParentDirectories(relativeOutputPath
, new DirectoryCopyPackagingElement(filePath
));
247 public PackagingElement
<?
> createFileCopyWithParentDirectories(@NotNull String filePath
, @NotNull String relativeOutputPath
) {
248 return createFileCopyWithParentDirectories(filePath
, relativeOutputPath
, null);
253 public PackagingElement
<?
> createFileCopyWithParentDirectories(@NotNull String filePath
,
254 @NotNull String relativeOutputPath
,
255 @Nullable String outputFileName
) {
256 final FileCopyPackagingElement file
= new FileCopyPackagingElement(filePath
, outputFileName
);
257 return createParentDirectories(relativeOutputPath
, file
);
262 public PackagingElement
<?
> createParentDirectories(@NotNull String relativeOutputPath
, @NotNull PackagingElement
<?
> element
) {
263 return createParentDirectories(relativeOutputPath
, Collections
.singletonList(element
)).get(0);
268 public List
<?
extends PackagingElement
<?
>> createParentDirectories(@NotNull String relativeOutputPath
, @NotNull List
<?
extends PackagingElement
<?
>> elements
) {
269 relativeOutputPath
= StringUtil
.trimStart(relativeOutputPath
, "/");
270 if (relativeOutputPath
.length() == 0) {
273 int slash
= relativeOutputPath
.indexOf('/');
274 if (slash
== -1) slash
= relativeOutputPath
.length();
275 String rootName
= relativeOutputPath
.substring(0, slash
);
276 String pathTail
= relativeOutputPath
.substring(slash
);
277 final DirectoryPackagingElement root
= createDirectory(rootName
);
278 final CompositePackagingElement
<?
> last
= getOrCreateDirectory(root
, pathTail
);
279 last
.addOrFindChildren(elements
);
280 return Collections
.singletonList(root
);
283 public static PackagingElement
<?
> createDirectoryOrArchiveWithParents(@NotNull String path
, final boolean archive
) {
284 path
= FileUtil
.toSystemIndependentName(path
);
285 final String parentPath
= PathUtil
.getParentPath(path
);
286 final String fileName
= PathUtil
.getFileName(path
);
287 final PackagingElement
<?
> element
= archive ?
new ArchivePackagingElement(fileName
) : new DirectoryPackagingElement(fileName
);
288 return getInstance().createParentDirectories(parentPath
, element
);
291 private static class ArtifactRootElementType
extends PackagingElementType
<ArtifactRootElement
<?
>> {
292 protected ArtifactRootElementType() {
297 public boolean canCreate(@NotNull ArtifactEditorContext context
, @NotNull Artifact artifact
) {
302 public List
<?
extends ArtifactRootElement
<?
>> chooseAndCreate(@NotNull ArtifactEditorContext context
, @NotNull Artifact artifact
,
303 @NotNull CompositePackagingElement
<?
> parent
) {
304 throw new UnsupportedOperationException("'create' not implemented in " + getClass().getName());
308 public ArtifactRootElement
<?
> createEmpty(@NotNull Project project
) {
309 return new ArtifactRootElementImpl();