2 * Copyright (c) 2007, Your Corporation. All Rights Reserved.
6 * created at Jan 3, 2002
9 package com
.intellij
.compiler
;
11 import com
.intellij
.CommonBundle
;
12 import com
.intellij
.ProjectTopics
;
13 import com
.intellij
.compiler
.impl
.javaCompiler
.BackendCompiler
;
14 import com
.intellij
.compiler
.impl
.javaCompiler
.api
.CompilerAPICompiler
;
15 import com
.intellij
.compiler
.impl
.javaCompiler
.eclipse
.EclipseCompiler
;
16 import com
.intellij
.compiler
.impl
.javaCompiler
.eclipse
.EclipseEmbeddedCompiler
;
17 import com
.intellij
.compiler
.impl
.javaCompiler
.javac
.JavacCompiler
;
18 import com
.intellij
.compiler
.impl
.javaCompiler
.jikes
.JikesCompiler
;
19 import com
.intellij
.openapi
.application
.ApplicationManager
;
20 import com
.intellij
.openapi
.application
.ApplicationNamesInfo
;
21 import com
.intellij
.openapi
.application
.ex
.ApplicationManagerEx
;
22 import com
.intellij
.openapi
.compiler
.CompilerBundle
;
23 import com
.intellij
.openapi
.compiler
.options
.ExcludedEntriesConfiguration
;
24 import com
.intellij
.openapi
.components
.*;
25 import com
.intellij
.openapi
.diagnostic
.Logger
;
26 import com
.intellij
.openapi
.module
.Module
;
27 import com
.intellij
.openapi
.module
.ModuleManager
;
28 import com
.intellij
.openapi
.project
.ModuleListener
;
29 import com
.intellij
.openapi
.project
.Project
;
30 import com
.intellij
.openapi
.ui
.InputValidator
;
31 import com
.intellij
.openapi
.ui
.Messages
;
32 import com
.intellij
.openapi
.util
.*;
33 import com
.intellij
.openapi
.util
.io
.FileUtil
;
34 import com
.intellij
.openapi
.util
.text
.StringUtil
;
35 import com
.intellij
.openapi
.vfs
.VirtualFile
;
36 import com
.intellij
.util
.ArrayUtil
;
37 import org
.apache
.oro
.text
.regex
.*;
38 import org
.jdom
.Element
;
39 import org
.jetbrains
.annotations
.NonNls
;
40 import org
.jetbrains
.annotations
.NotNull
;
41 import org
.jetbrains
.annotations
.Nullable
;
47 name
= "CompilerConfiguration",
49 @Storage(id
= "default", file
= "$PROJECT_FILE$")
50 ,@Storage(id
= "dir", file
= "$PROJECT_CONFIG_DIR$/compiler.xml", scheme
= StorageScheme
.DIRECTORY_BASED
)
53 public class CompilerConfigurationImpl
extends CompilerConfiguration
implements PersistentStateComponent
<Element
>, ProjectComponent
{
54 private static final Logger LOG
= Logger
.getInstance("#com.intellij.compiler.CompilerConfiguration");
55 @NonNls public static final String TESTS_EXTERNAL_COMPILER_HOME_PROPERTY_NAME
= "tests.external.compiler.home";
56 public static final int DEPENDENCY_FORMAT_VERSION
= 53;
58 @SuppressWarnings({"WeakerAccess"}) public String DEFAULT_COMPILER
;
59 @NotNull private BackendCompiler myDefaultJavaCompiler
;
61 // extensions of the files considered as resource files
62 private final List
<Pattern
> myRegexpResourcePaterns
= new ArrayList
<Pattern
>(getDefaultRegexpPatterns());
63 // extensions of the files considered as resource files. If present, Overrides patterns in old regexp format stored in myRegexpResourcePaterns
64 private final List
<String
> myWildcardPatterns
= new ArrayList
<String
>();
65 private final List
<Pair
<Pattern
, Pattern
>> myCompiledPatterns
= new ArrayList
<Pair
<Pattern
, Pattern
>>();
66 private final List
<Pair
<Pattern
, Pattern
>> myNegatedCompiledPatterns
= new ArrayList
<Pair
<Pattern
, Pattern
>>();
67 private boolean myWildcardPatternsInitialized
= false;
68 private final Project myProject
;
69 private final ModuleManager myModuleManager
;
70 private final ExcludedEntriesConfiguration myExcludedEntriesConfiguration
;
72 private final Collection
<BackendCompiler
> myRegisteredCompilers
= new ArrayList
<BackendCompiler
>();
73 private JavacCompiler JAVAC_EXTERNAL_BACKEND
;
74 private final Perl5Matcher myPatternMatcher
= new Perl5Matcher();
77 loadDefaultWildcardPatterns();
80 private boolean myEnableAnnotationProcessors
= false;
81 private final Map
<String
, String
> myProcessorsMap
= new HashMap
<String
, String
>(); // map: AnnotationProcessorName -> options
82 private boolean myObtainProcessorsFromClasspath
= true;
83 private String myProcessorPath
= "";
84 private final Set
<Module
> myExcludedModules
= new HashSet
<Module
>();
85 private final Set
<String
> myExcludedModuleNames
= new HashSet
<String
>();
88 public CompilerConfigurationImpl(Project project
, ModuleManager moduleManager
) {
90 myModuleManager
= moduleManager
;
91 myExcludedEntriesConfiguration
= new ExcludedEntriesConfiguration();
92 Disposer
.register(project
, myExcludedEntriesConfiguration
);
93 project
.getMessageBus().connect(project
).subscribe(ProjectTopics
.MODULES
, new ModuleListener() {
94 public void modulesRenamed(Project project
, List
<Module
> modules
) {
97 public void moduleRemoved(Project project
, Module module
) {
100 public void beforeModuleRemoved(Project project
, Module module
) {
101 myExcludedModules
.remove(module
);
102 myExcludedModuleNames
.remove(module
.getName());
105 public void moduleAdded(Project project
, Module module
) {
106 if (myExcludedModuleNames
.remove(module
.getName())) {
107 myExcludedModules
.add(module
);
113 public Element
getState() {
115 @NonNls final Element e
= new Element("state");
119 catch (WriteExternalException e1
) {
125 public void loadState(Element state
) {
129 catch (InvalidDataException e
) {
134 private void loadDefaultWildcardPatterns() {
135 if (!myWildcardPatterns
.isEmpty()) {
136 removeWildcardPatterns();
139 addWildcardResourcePattern("?*.properties");
140 addWildcardResourcePattern("?*.xml");
141 addWildcardResourcePattern("?*.gif");
142 addWildcardResourcePattern("?*.png");
143 addWildcardResourcePattern("?*.jpeg");
144 addWildcardResourcePattern("?*.jpg");
145 addWildcardResourcePattern("?*.html");
146 addWildcardResourcePattern("?*.dtd");
147 addWildcardResourcePattern("?*.tld");
148 addWildcardResourcePattern("?*.ftl");
150 catch (MalformedPatternException e
) {
155 private static List
<Pattern
> getDefaultRegexpPatterns() {
157 return Arrays
.asList(compilePattern(".+\\.(properties|xml|html|dtd|tld)"), compilePattern(".+\\.(gif|png|jpeg|jpg)"));
159 catch (MalformedPatternException e
) {
162 return Collections
.emptyList();
165 public static String
getTestsExternalCompilerHome() {
166 String compilerHome
= System
.getProperty(TESTS_EXTERNAL_COMPILER_HOME_PROPERTY_NAME
, null);
167 if (compilerHome
== null) {
168 if (SystemInfo
.isMac
) {
169 compilerHome
= new File(System
.getProperty("java.home")).getAbsolutePath();
172 compilerHome
= new File(System
.getProperty("java.home")).getParentFile().getAbsolutePath();
178 private static Pattern
compilePattern(@NonNls String s
) throws MalformedPatternException
{
180 final PatternCompiler compiler
= new Perl5Compiler();
181 return SystemInfo
.isFileSystemCaseSensitive? compiler
.compile(s
) : compiler
.compile(s
, Perl5Compiler
.CASE_INSENSITIVE_MASK
);
183 catch (org
.apache
.oro
.text
.regex
.MalformedPatternException ex
) {
184 throw new MalformedPatternException(ex
);
188 public void disposeComponent() {
191 public void initComponent() { }
193 public void projectClosed() {
196 public JavacCompiler
getJavacCompiler() {
197 if (JAVAC_EXTERNAL_BACKEND
== null) {
200 return JAVAC_EXTERNAL_BACKEND
;
203 public void projectOpened() {
207 private void createCompilers() {
208 JAVAC_EXTERNAL_BACKEND
= new JavacCompiler(myProject
);
209 myRegisteredCompilers
.add(JAVAC_EXTERNAL_BACKEND
);
211 if (!ApplicationManager
.getApplication().isUnitTestMode()) {
212 final BackendCompiler JIKES_BACKEND
= new JikesCompiler(myProject
);
213 myRegisteredCompilers
.add(JIKES_BACKEND
);
215 if (EclipseCompiler
.isInitialized()) {
216 final EclipseCompiler eclipse
= new EclipseCompiler(myProject
);
217 myRegisteredCompilers
.add(eclipse
);
220 if (ApplicationManagerEx
.getApplicationEx().isInternal()) {
222 final EclipseEmbeddedCompiler eclipseEmbedded
= new EclipseEmbeddedCompiler(myProject
);
223 myRegisteredCompilers
.add(eclipseEmbedded
);
225 catch (NoClassDefFoundError e
) {
226 // eclipse jar must be not in the classpath
230 if (ApplicationManagerEx
.getApplicationEx().isInternal()) {
232 CompilerAPICompiler inprocessJavaCompiler
= new CompilerAPICompiler(myProject
);
233 myRegisteredCompilers
.add(inprocessJavaCompiler
);
235 catch (NoClassDefFoundError e
) {
241 myDefaultJavaCompiler
= JAVAC_EXTERNAL_BACKEND
;
242 for (BackendCompiler compiler
: myRegisteredCompilers
) {
243 if (compiler
.getId().equals(DEFAULT_COMPILER
)) {
244 myDefaultJavaCompiler
= compiler
;
248 DEFAULT_COMPILER
= myDefaultJavaCompiler
.getId();
251 public Collection
<BackendCompiler
> getRegisteredJavaCompilers() {
252 return myRegisteredCompilers
;
255 public String
[] getResourceFilePatterns() {
256 return getWildcardPatterns();
259 private String
[] getRegexpPatterns() {
260 String
[] patterns
= ArrayUtil
.newStringArray(myRegexpResourcePaterns
.size());
262 for (final Pattern myRegexpResourcePatern
: myRegexpResourcePaterns
) {
263 patterns
[index
++] = myRegexpResourcePatern
.getPattern();
268 private String
[] getWildcardPatterns() {
269 return ArrayUtil
.toStringArray(myWildcardPatterns
);
272 public void addResourceFilePattern(String namePattern
) throws MalformedPatternException
{
273 addWildcardResourcePattern(namePattern
);
276 // need this method only for handling patterns in old regexp format
277 private void addRegexpPattern(String namePattern
) throws MalformedPatternException
{
278 Pattern pattern
= compilePattern(namePattern
);
279 if (pattern
!= null) {
280 myRegexpResourcePaterns
.add(pattern
);
284 public ExcludedEntriesConfiguration
getExcludedEntriesConfiguration() {
285 return myExcludedEntriesConfiguration
;
288 public boolean isExcludedFromCompilation(final VirtualFile virtualFile
) {
289 return myExcludedEntriesConfiguration
.isExcluded(virtualFile
);
293 public boolean isResourceFile(VirtualFile virtualFile
) {
294 return isResourceFile(virtualFile
.getName(), virtualFile
.getParent());
297 public boolean isAnnotationProcessorsEnabled() {
298 return myEnableAnnotationProcessors
;
301 public void setAnnotationProcessorsEnabled(boolean enableAnnotationProcessors
) {
302 myEnableAnnotationProcessors
= enableAnnotationProcessors
;
305 public boolean isObtainProcessorsFromClasspath() {
306 return myObtainProcessorsFromClasspath
;
309 public void setObtainProcessorsFromClasspath(boolean obtainProcessorsFromClasspath
) {
310 myObtainProcessorsFromClasspath
= obtainProcessorsFromClasspath
;
313 public String
getProcessorPath() {
314 return myProcessorPath
;
317 public void setProcessorsPath(String processorsPath
) {
318 myProcessorPath
= processorsPath
;
321 public Map
<String
, String
> getAnnotationProcessorsMap() {
322 return Collections
.unmodifiableMap(myProcessorsMap
);
325 public void setAnnotationProcessorsMap(Map
<String
, String
> map
) {
326 myProcessorsMap
.clear();
327 myProcessorsMap
.putAll(map
);
330 public Set
<Module
> getExcludedModules() {
331 return Collections
.unmodifiableSet(myExcludedModules
);
334 public void setExcludedModules(Collection
<Module
> modules
) {
335 myExcludedModules
.clear();
336 myExcludedModuleNames
.clear();
337 myExcludedModules
.addAll(modules
);
340 private void addWildcardResourcePattern(@NonNls final String wildcardPattern
) throws MalformedPatternException
{
341 final Pair
<Pattern
, Pattern
> pattern
= convertToRegexp(wildcardPattern
);
342 if (pattern
!= null) {
343 myWildcardPatterns
.add(wildcardPattern
);
344 if (isPatternNegated(wildcardPattern
)) {
345 myNegatedCompiledPatterns
.add(pattern
);
348 myCompiledPatterns
.add(pattern
);
353 public void removeResourceFilePatterns() {
354 removeWildcardPatterns();
357 private void removeRegexpPatterns() {
358 myRegexpResourcePaterns
.clear();
361 private void removeWildcardPatterns() {
362 myWildcardPatterns
.clear();
363 myCompiledPatterns
.clear();
364 myNegatedCompiledPatterns
.clear();
367 private static Pair
<Pattern
, Pattern
> convertToRegexp(String wildcardPattern
) {
368 if (isPatternNegated(wildcardPattern
)) {
369 wildcardPattern
= wildcardPattern
.substring(1);
372 wildcardPattern
= FileUtil
.toSystemIndependentName(wildcardPattern
);
374 String dirPattern
= null;
375 int slash
= wildcardPattern
.lastIndexOf('/');
377 dirPattern
= wildcardPattern
.substring(0, slash
+ 1);
378 wildcardPattern
= wildcardPattern
.substring(slash
+ 1);
379 if (!dirPattern
.startsWith("/")) {
380 dirPattern
= "/" + dirPattern
;
382 //now dirPattern starts and ends with '/'
384 dirPattern
= normalizeWildcards(dirPattern
);
386 dirPattern
= StringUtil
.replace(dirPattern
, "/.*.*/", "(/.*)?/");
387 dirPattern
= StringUtil
.trimEnd(dirPattern
, "/");
389 dirPattern
= optimize(dirPattern
);
391 dirPattern
= ".*" + dirPattern
;
395 wildcardPattern
= normalizeWildcards(wildcardPattern
);
396 wildcardPattern
= optimize(wildcardPattern
);
398 final Pattern dirCompiled
= dirPattern
== null ?
null : compilePattern(dirPattern
);
399 return Pair
.create(compilePattern(wildcardPattern
), dirCompiled
);
402 private static String
optimize(String wildcardPattern
) {
403 return wildcardPattern
.replaceAll("(?:\\.\\*)+", ".*");
406 private static String
normalizeWildcards(String wildcardPattern
) {
407 wildcardPattern
= StringUtil
.replace(wildcardPattern
, "\\!", "!");
408 wildcardPattern
= StringUtil
.replace(wildcardPattern
, ".", "\\.");
409 wildcardPattern
= StringUtil
.replace(wildcardPattern
, "*?", ".+");
410 wildcardPattern
= StringUtil
.replace(wildcardPattern
, "?*", ".+");
411 wildcardPattern
= StringUtil
.replace(wildcardPattern
, "*", ".*");
412 wildcardPattern
= StringUtil
.replace(wildcardPattern
, "?", ".");
413 return wildcardPattern
;
416 public static boolean isPatternNegated(String wildcardPattern
) {
417 return wildcardPattern
.length() > 1 && wildcardPattern
.charAt(0) == '!';
420 public boolean isResourceFile(String name
) {
421 return isResourceFile(name
, null);
424 private boolean matches(String s
, Pattern p
) {
425 synchronized (myPatternMatcher
) {
427 return myPatternMatcher
.matches(s
, p
);
429 catch (Exception e
) {
430 LOG
.error("Exception matching file name \"" + s
+ "\" against the pattern \"" + p
+ "\"", e
);
436 private boolean isResourceFile(String name
, @Nullable VirtualFile parent
) {
437 final Ref
<String
> parentRef
= Ref
.create(null);
438 //noinspection ForLoopReplaceableByForEach
439 for (int i
= 0; i
< myCompiledPatterns
.size(); i
++) {
440 if (matches(name
, parent
, parentRef
, myCompiledPatterns
.get(i
))) {
445 if (myNegatedCompiledPatterns
.isEmpty()) {
449 //noinspection ForLoopReplaceableByForEach
450 for (int i
= 0; i
< myNegatedCompiledPatterns
.size(); i
++) {
451 if (matches(name
, parent
, parentRef
, myNegatedCompiledPatterns
.get(i
))) {
458 private boolean matches(String name
, VirtualFile parent
, Ref
<String
> parentRef
, Pair
<Pattern
, Pattern
> pair
) {
459 if (!matches(name
, pair
.first
)) {
463 final Pattern dirPattern
= pair
.second
;
464 if (dirPattern
== null || parent
== null) {
468 String parentPath
= parentRef
.get();
469 if (parentPath
== null) {
470 parentRef
.set(parentPath
= parent
.getPath());
472 return matches(parentPath
, dirPattern
);
476 @NonNls private static final String EXCLUDE_FROM_COMPILE
= "excludeFromCompile";
477 @NonNls private static final String RESOURCE_EXTENSIONS
= "resourceExtensions";
478 @NonNls private static final String ANNOTATION_PROCESSING
= "annotationProcessing";
479 @NonNls private static final String WILDCARD_RESOURCE_PATTERNS
= "wildcardResourcePatterns";
480 @NonNls private static final String ENTRY
= "entry";
481 @NonNls private static final String NAME
= "name";
483 public void readExternal(Element parentNode
) throws InvalidDataException
{
484 DefaultJDOMExternalizer
.readExternal(this, parentNode
);
486 Element node
= parentNode
.getChild(EXCLUDE_FROM_COMPILE
);
488 myExcludedEntriesConfiguration
.readExternal(node
);
492 removeRegexpPatterns();
493 node
= parentNode
.getChild(RESOURCE_EXTENSIONS
);
495 for (final Object o
: node
.getChildren(ENTRY
)) {
496 Element element
= (Element
)o
;
497 String pattern
= element
.getAttributeValue(NAME
);
498 if (pattern
!= null && !"".equals(pattern
)) {
499 addRegexpPattern(pattern
);
504 removeWildcardPatterns();
505 node
= parentNode
.getChild(WILDCARD_RESOURCE_PATTERNS
);
507 myWildcardPatternsInitialized
= true;
508 for (final Object o
: node
.getChildren(ENTRY
)) {
509 final Element element
= (Element
)o
;
510 String pattern
= element
.getAttributeValue(NAME
);
511 if (pattern
!= null && !"".equals(pattern
)) {
512 addWildcardResourcePattern(pattern
);
517 catch (MalformedPatternException e
) {
518 throw new InvalidDataException(e
);
521 final Element annotationProcessingSettings
= parentNode
.getChild(ANNOTATION_PROCESSING
);
522 if (annotationProcessingSettings
!= null) {
523 myEnableAnnotationProcessors
= Boolean
.valueOf(annotationProcessingSettings
.getAttributeValue("enabled", "false"));
524 myObtainProcessorsFromClasspath
= Boolean
.valueOf(annotationProcessingSettings
.getAttributeValue("useClasspath", "true"));
526 final StringBuilder pathBuilder
= new StringBuilder();
527 for (Element pathElement
: ((Collection
<Element
>)annotationProcessingSettings
.getChildren("processorPath"))) {
528 final String path
= pathElement
.getAttributeValue("value");
530 if (pathBuilder
.length() > 0) {
531 pathBuilder
.append(File
.pathSeparator
);
533 pathBuilder
.append(path
);
536 myProcessorPath
= pathBuilder
.toString();
538 myProcessorsMap
.clear();
539 for (Element processorChild
: ((Collection
<Element
>)annotationProcessingSettings
.getChildren("processor"))) {
540 final String name
= processorChild
.getAttributeValue("name");
541 final String options
= processorChild
.getAttributeValue("options", "");
542 myProcessorsMap
.put(name
, options
);
544 myExcludedModules
.clear();
545 myExcludedModuleNames
.clear();
546 final Collection
<Element
> excluded
= (Collection
<Element
>)annotationProcessingSettings
.getChildren("excludeModule");
547 if (excluded
.size() > 0) {
548 final Map
<String
, Module
> moduleMap
= new com
.intellij
.util
.containers
.HashMap
<String
, Module
>();
549 for (Module module
: myModuleManager
.getModules()) {
550 moduleMap
.put(module
.getName(), module
);
552 for (Element moduleElement
: excluded
) {
553 final String name
= moduleElement
.getAttributeValue("name");
555 final Module module
= moduleMap
.get(name
);
556 if (module
!= null) {
557 myExcludedModules
.add(module
);
560 myExcludedModuleNames
.add(name
);
568 public void writeExternal(Element parentNode
) throws WriteExternalException
{
569 DefaultJDOMExternalizer
.writeExternal(this, parentNode
);
571 if(myExcludedEntriesConfiguration
.getExcludeEntryDescriptions().length
> 0) {
572 Element newChild
= new Element(EXCLUDE_FROM_COMPILE
);
573 myExcludedEntriesConfiguration
.writeExternal(newChild
);
574 parentNode
.addContent(newChild
);
577 final Element newChild
= new Element(RESOURCE_EXTENSIONS
);
578 for (final String pattern
: getRegexpPatterns()) {
579 final Element entry
= new Element(ENTRY
);
580 entry
.setAttribute(NAME
, pattern
);
581 newChild
.addContent(entry
);
583 parentNode
.addContent(newChild
);
585 if (myWildcardPatternsInitialized
|| !myWildcardPatterns
.isEmpty()) {
586 final Element wildcardPatterns
= new Element(WILDCARD_RESOURCE_PATTERNS
);
587 for (final String wildcardPattern
: myWildcardPatterns
) {
588 final Element entry
= new Element(ENTRY
);
589 entry
.setAttribute(NAME
, wildcardPattern
);
590 wildcardPatterns
.addContent(entry
);
592 parentNode
.addContent(wildcardPatterns
);
595 final Element annotationProcessingSettings
= new Element(ANNOTATION_PROCESSING
);
596 parentNode
.addContent(annotationProcessingSettings
);
597 annotationProcessingSettings
.setAttribute("enabled", String
.valueOf(myEnableAnnotationProcessors
));
598 annotationProcessingSettings
.setAttribute("useClasspath", String
.valueOf(myObtainProcessorsFromClasspath
));
599 if (myProcessorPath
.length() > 0) {
600 final StringTokenizer tokenizer
= new StringTokenizer(myProcessorPath
, File
.pathSeparator
, false);
601 while (tokenizer
.hasMoreTokens()) {
602 final String path
= tokenizer
.nextToken();
603 final Element pathElement
= new Element("processorPath");
604 annotationProcessingSettings
.addContent(pathElement
);
605 pathElement
.setAttribute("value", path
);
608 for (Map
.Entry
<String
, String
> entry
: myProcessorsMap
.entrySet()) {
609 final Element processor
= new Element("processor");
610 annotationProcessingSettings
.addContent(processor
);
611 processor
.setAttribute("name", entry
.getKey());
612 processor
.setAttribute("options", entry
.getValue());
614 final List
<Module
> modules
= new ArrayList
<Module
>(getExcludedModules());
615 Collections
.sort(modules
, new Comparator
<Module
>() {
616 public int compare(Module o1
, Module o2
) {
617 return o1
.getName().compareToIgnoreCase(o2
.getName());
620 for (Module module
: modules
) {
621 final Element moduleElement
= new Element("excludeModule");
622 annotationProcessingSettings
.addContent(moduleElement
);
623 moduleElement
.setAttribute("name", module
.getName());
628 public String
getComponentName() {
629 return "CompilerConfiguration";
632 public BackendCompiler
getDefaultCompiler() {
633 if (JAVAC_EXTERNAL_BACKEND
== null) {
636 return myDefaultJavaCompiler
;
639 public void setDefaultCompiler(BackendCompiler defaultCompiler
) {
640 myDefaultJavaCompiler
= defaultCompiler
;
641 DEFAULT_COMPILER
= defaultCompiler
.getId();
644 public void convertPatterns() {
645 if (!needPatternConversion()) {
651 ok
= doConvertPatterns();
653 catch (MalformedPatternException e
) {
657 final String initialPatternString
= patternsToString(getRegexpPatterns());
658 final String message
= CompilerBundle
.message(
659 "message.resource.patterns.format.changed",
660 ApplicationNamesInfo
.getInstance().getProductName(),
661 initialPatternString
,
662 CommonBundle
.getOkButtonText(),
663 CommonBundle
.getCancelButtonText()
665 final String wildcardPatterns
= Messages
.showInputDialog(
666 myProject
, message
, CompilerBundle
.message("pattern.conversion.dialog.title"), Messages
.getWarningIcon(), initialPatternString
, new InputValidator() {
667 public boolean checkInput(String inputString
) {
670 public boolean canClose(String inputString
) {
671 final StringTokenizer tokenizer
= new StringTokenizer(inputString
, ";", false);
672 StringBuilder malformedPatterns
= new StringBuilder();
674 while (tokenizer
.hasMoreTokens()) {
675 String pattern
= tokenizer
.nextToken();
677 addWildcardResourcePattern(pattern
);
679 catch (MalformedPatternException e
) {
680 malformedPatterns
.append("\n\n");
681 malformedPatterns
.append(pattern
);
682 malformedPatterns
.append(": ");
683 malformedPatterns
.append(e
.getMessage());
687 if (malformedPatterns
.length() > 0) {
688 Messages
.showErrorDialog(CompilerBundle
.message("error.bad.resource.patterns", malformedPatterns
.toString()),
689 CompilerBundle
.message("bad.resource.patterns.dialog.title"));
690 removeWildcardPatterns();
696 if (wildcardPatterns
== null) { // cancel pressed
697 loadDefaultWildcardPatterns();
702 myWildcardPatternsInitialized
= true;
706 private boolean needPatternConversion() {
707 return !myWildcardPatternsInitialized
&& !myRegexpResourcePaterns
.isEmpty();
710 private boolean doConvertPatterns() throws MalformedPatternException
{
711 final String
[] regexpPatterns
= getRegexpPatterns();
712 final List
<String
> converted
= new ArrayList
<String
>();
713 final Pattern multipleExtensionsPatternPattern
= compilePattern("\\.\\+\\\\\\.\\((\\w+(?:\\|\\w+)*)\\)");
714 final Pattern singleExtensionPatternPattern
= compilePattern("\\.\\+\\\\\\.(\\w+)");
715 final Perl5Matcher matcher
= new Perl5Matcher();
716 for (final String regexpPattern
: regexpPatterns
) {
717 //final Matcher multipleExtensionsMatcher = multipleExtensionsPatternPattern.matcher(regexpPattern);
718 if (matcher
.matches(regexpPattern
, multipleExtensionsPatternPattern
)) {
719 final MatchResult match
= matcher
.getMatch();
720 final StringTokenizer tokenizer
= new StringTokenizer(match
.group(1), "|", false);
721 while (tokenizer
.hasMoreTokens()) {
722 converted
.add("?*." + tokenizer
.nextToken());
726 //final Matcher singleExtensionMatcher = singleExtensionPatternPattern.matcher(regexpPattern);
727 if (matcher
.matches(regexpPattern
, singleExtensionPatternPattern
)) {
728 final MatchResult match
= matcher
.getMatch();
729 converted
.add("?*." + match
.group(1));
736 for (final String aConverted
: converted
) {
737 addWildcardResourcePattern(aConverted
);
742 private static String
patternsToString(final String
[] patterns
) {
743 final StringBuilder extensionsString
= new StringBuilder();
744 for (int idx
= 0; idx
< patterns
.length
; idx
++) {
746 extensionsString
.append(";");
748 extensionsString
.append(patterns
[idx
]);
750 return extensionsString
.toString();