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
.openapi
.deployment
;
18 import com
.intellij
.compiler
.impl
.packagingCompiler
.BuildRecipeImpl
;
19 import com
.intellij
.openapi
.compiler
.CompileContext
;
20 import com
.intellij
.openapi
.compiler
.CompilerBundle
;
21 import com
.intellij
.openapi
.compiler
.CompilerMessageCategory
;
22 import com
.intellij
.openapi
.compiler
.make
.BuildRecipe
;
23 import com
.intellij
.openapi
.diagnostic
.Logger
;
24 import com
.intellij
.openapi
.module
.Module
;
25 import com
.intellij
.openapi
.util
.SystemInfo
;
26 import com
.intellij
.openapi
.util
.io
.FileUtil
;
27 import com
.intellij
.openapi
.vfs
.VfsUtil
;
28 import com
.intellij
.psi
.PsiFile
;
29 import com
.intellij
.psi
.xml
.XmlDocument
;
30 import com
.intellij
.psi
.xml
.XmlFile
;
31 import com
.intellij
.util
.descriptors
.ConfigFile
;
32 import org
.jetbrains
.annotations
.NotNull
;
33 import org
.jetbrains
.annotations
.Nullable
;
36 import java
.io
.FileFilter
;
37 import java
.io
.IOException
;
41 * @author Alexey Kudravtsev
43 public class DeploymentUtilImpl
extends DeploymentUtil
{
44 private static final Logger LOG
= Logger
.getInstance("#com.intellij.openapi.deployment.MakeUtilImpl");
46 public void copyFile(@NotNull final File fromFile
,
47 @NotNull final File toFile
,
48 @NotNull CompileContext context
,
49 @Nullable Set
<String
> writtenPaths
,
50 @Nullable FileFilter fileFilter
) throws IOException
{
51 if (fileFilter
!= null && !fileFilter
.accept(fromFile
)) {
54 checkPathDoNotNavigatesUpFromFile(fromFile
);
55 checkPathDoNotNavigatesUpFromFile(toFile
);
56 if (fromFile
.isDirectory()) {
57 final File
[] fromFiles
= fromFile
.listFiles();
59 for (File file
: fromFiles
) {
60 copyFile(file
, new File(toFile
, file
.getName()), context
, writtenPaths
, fileFilter
);
64 if (toFile
.isDirectory()) {
65 context
.addMessage(CompilerMessageCategory
.ERROR
,
66 CompilerBundle
.message("message.text.destination.is.directory", createCopyErrorMessage(fromFile
, toFile
)), null, -1, -1);
69 if (fromFile
.equals(toFile
)
70 || writtenPaths
!= null && !writtenPaths
.add(toFile
.getPath())) {
73 if (!FileUtil
.isFilePathAcceptable(toFile
, fileFilter
)) return;
74 if (context
.getProgressIndicator() != null) {
75 context
.getProgressIndicator().setText("Copying files");
76 context
.getProgressIndicator().setText2(fromFile
.getPath());
79 if (LOG
.isDebugEnabled()) {
80 LOG
.debug("Copy file '" + fromFile
+ "' to '"+toFile
+"'");
82 if (toFile
.exists() && !SystemInfo
.isFileSystemCaseSensitive
) {
83 File canonicalFile
= toFile
.getCanonicalFile();
84 if (!canonicalFile
.getAbsolutePath().equals(toFile
.getAbsolutePath())) {
85 FileUtil
.delete(toFile
);
88 FileUtil
.copy(fromFile
, toFile
);
90 catch (IOException e
) {
91 context
.addMessage(CompilerMessageCategory
.ERROR
, createCopyErrorMessage(fromFile
, toFile
) + ": "+e
.getLocalizedMessage(), null, -1, -1);
95 // OS X is sensitive for that
96 private static void checkPathDoNotNavigatesUpFromFile(File file
) {
97 String path
= file
.getPath();
98 int i
= path
.indexOf("..");
100 String filepath
= path
.substring(0,i
-1);
101 File filepart
= new File(filepath
);
102 if (filepart
.exists() && !filepart
.isDirectory()) {
103 LOG
.error("Incorrect file path: '" + path
+ '\'');
108 private static String
createCopyErrorMessage(final File fromFile
, final File toFile
) {
109 return CompilerBundle
.message("message.text.error.copying.file.to.file", FileUtil
.toSystemDependentName(fromFile
.getPath()),
110 FileUtil
.toSystemDependentName(toFile
.getPath()));
113 public final boolean addItemsRecursively(@NotNull BuildRecipe items
, @NotNull File root
, String outputRelativePath
) {
114 if (outputRelativePath
== null) outputRelativePath
= "";
115 outputRelativePath
= trimForwardSlashes(outputRelativePath
);
117 items
.addFileCopyInstruction(root
, true, outputRelativePath
);
121 public void reportDeploymentDescriptorDoesNotExists(ConfigFile descriptor
, CompileContext context
, Module module
) {
122 final String description
= module
.getModuleType().getName() + " '" + module
.getName() + '\'';
123 String descriptorPath
= VfsUtil
.urlToPath(descriptor
.getUrl());
124 final String message
=
125 CompilerBundle
.message("message.text.compiling.item.deployment.descriptor.could.not.be.found", description
, descriptorPath
);
126 context
.addMessage(CompilerMessageCategory
.ERROR
, message
, null, -1, -1);
129 public void checkConfigFile(final ConfigFile descriptor
, final CompileContext compileContext
, final Module module
) {
130 if (new File(VfsUtil
.urlToPath(descriptor
.getUrl())).exists()) {
131 String message
= getConfigFileErrorMessage(descriptor
);
132 if (message
!= null) {
133 final String moduleDescription
= module
.getModuleType().getName() + " '" + module
.getName() + '\'';
134 compileContext
.addMessage(CompilerMessageCategory
.ERROR
,
135 CompilerBundle
.message("message.text.compiling.module.message", moduleDescription
, message
),
136 descriptor
.getUrl(), -1, -1);
140 DeploymentUtil
.getInstance().reportDeploymentDescriptorDoesNotExists(descriptor
, compileContext
, module
);
144 public BuildRecipe
createBuildRecipe() {
145 return new BuildRecipeImpl();
149 public String
getConfigFileErrorMessage(final ConfigFile configFile
) {
150 if (configFile
.getVirtualFile() == null) {
151 String path
= FileUtil
.toSystemDependentName(VfsUtil
.urlToPath(configFile
.getUrl()));
152 return CompilerBundle
.message("mesage.text.deployment.descriptor.file.not.exist", path
);
154 PsiFile psiFile
= configFile
.getPsiFile();
155 if (psiFile
== null || !psiFile
.isValid()) {
156 return CompilerBundle
.message("message.text.deployment.description.invalid.file");
159 if (psiFile
instanceof XmlFile
) {
160 XmlDocument document
= ((XmlFile
)psiFile
).getDocument();
161 if (document
== null || document
.getRootTag() == null) {
162 return CompilerBundle
.message("message.text.xml.file.invalid", FileUtil
.toSystemDependentName(VfsUtil
.urlToPath(configFile
.getUrl())));