fix processor path externalization
[fedora-idea.git] / java / compiler / impl / src / com / intellij / compiler / CompilerConfigurationImpl.java
blob8f30f69772d499395e2fe5be81bcdb3a7f91edf9
1 /*
2 * Copyright (c) 2007, Your Corporation. All Rights Reserved.
3 */
5 /**
6 * created at Jan 3, 2002
7 * @author Jeka
8 */
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;
43 import java.io.File;
44 import java.util.*;
46 @State(
47 name = "CompilerConfiguration",
48 storages = {
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) {
89 myProject = project;
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() {
114 try {
115 @NonNls final Element e = new Element("state");
116 writeExternal(e);
117 return e;
119 catch (WriteExternalException e1) {
120 LOG.error(e1);
121 return null;
125 public void loadState(Element state) {
126 try {
127 readExternal(state);
129 catch (InvalidDataException e) {
130 LOG.error(e);
134 private void loadDefaultWildcardPatterns() {
135 if (!myWildcardPatterns.isEmpty()) {
136 removeWildcardPatterns();
138 try {
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) {
151 LOG.error(e);
155 private static List<Pattern> getDefaultRegexpPatterns() {
156 try {
157 return Arrays.asList(compilePattern(".+\\.(properties|xml|html|dtd|tld)"), compilePattern(".+\\.(gif|png|jpeg|jpg)"));
159 catch (MalformedPatternException e) {
160 LOG.error(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();
171 else {
172 compilerHome = new File(System.getProperty("java.home")).getParentFile().getAbsolutePath();
175 return compilerHome;
178 private static Pattern compilePattern(@NonNls String s) throws MalformedPatternException {
179 try {
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) {
198 createCompilers();
200 return JAVAC_EXTERNAL_BACKEND;
203 public void projectOpened() {
204 createCompilers();
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()) {
221 try {
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()) {
231 try {
232 CompilerAPICompiler inprocessJavaCompiler = new CompilerAPICompiler(myProject);
233 myRegisteredCompilers.add(inprocessJavaCompiler);
235 catch (NoClassDefFoundError e) {
236 // wrong JDK
241 myDefaultJavaCompiler = JAVAC_EXTERNAL_BACKEND;
242 for (BackendCompiler compiler : myRegisteredCompilers) {
243 if (compiler.getId().equals(DEFAULT_COMPILER)) {
244 myDefaultJavaCompiler = compiler;
245 break;
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());
261 int index = 0;
262 for (final Pattern myRegexpResourcePatern : myRegexpResourcePaterns) {
263 patterns[index++] = myRegexpResourcePatern.getPattern();
265 return patterns;
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);
292 @Override
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);
347 else {
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('/');
376 if (slash >= 0) {
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) {
426 try {
427 return myPatternMatcher.matches(s, p);
429 catch (Exception e) {
430 LOG.error("Exception matching file name \"" + s + "\" against the pattern \"" + p + "\"", e);
431 return false;
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))) {
441 return true;
445 if (myNegatedCompiledPatterns.isEmpty()) {
446 return false;
449 //noinspection ForLoopReplaceableByForEach
450 for (int i = 0; i < myNegatedCompiledPatterns.size(); i++) {
451 if (matches(name, parent, parentRef, myNegatedCompiledPatterns.get(i))) {
452 return false;
455 return true;
458 private boolean matches(String name, VirtualFile parent, Ref<String> parentRef, Pair<Pattern, Pattern> pair) {
459 if (!matches(name, pair.first)) {
460 return false;
463 final Pattern dirPattern = pair.second;
464 if (dirPattern == null || parent == null) {
465 return true;
468 String parentPath = parentRef.get();
469 if (parentPath == null) {
470 parentRef.set(parentPath = parent.getPath());
472 return matches(parentPath, dirPattern);
475 // property names
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);
487 if (node != null) {
488 myExcludedEntriesConfiguration.readExternal(node);
491 try {
492 removeRegexpPatterns();
493 node = parentNode.getChild(RESOURCE_EXTENSIONS);
494 if (node != null) {
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);
506 if (node != null) {
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");
529 if (path != null) {
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");
554 if (name != null) {
555 final Module module = moduleMap.get(name);
556 if (module != null) {
557 myExcludedModules.add(module);
559 else {
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());
627 @NotNull @NonNls
628 public String getComponentName() {
629 return "CompilerConfiguration";
632 public BackendCompiler getDefaultCompiler() {
633 if (JAVAC_EXTERNAL_BACKEND == null) {
634 createCompilers();
636 return myDefaultJavaCompiler;
639 public void setDefaultCompiler(BackendCompiler defaultCompiler) {
640 myDefaultJavaCompiler = defaultCompiler;
641 DEFAULT_COMPILER = defaultCompiler.getId();
644 public void convertPatterns() {
645 if (!needPatternConversion()) {
646 return;
648 try {
649 boolean ok;
650 try {
651 ok = doConvertPatterns();
653 catch (MalformedPatternException e) {
654 ok = false;
656 if (!ok) {
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) {
668 return true;
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();
676 try {
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();
691 return false;
693 return true;
696 if (wildcardPatterns == null) { // cancel pressed
697 loadDefaultWildcardPatterns();
701 finally {
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());
725 else {
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));
731 else {
732 return false;
736 for (final String aConverted : converted) {
737 addWildcardResourcePattern(aConverted);
739 return true;
742 private static String patternsToString(final String[] patterns) {
743 final StringBuilder extensionsString = new StringBuilder();
744 for (int idx = 0; idx < patterns.length; idx++) {
745 if (idx > 0) {
746 extensionsString.append(";");
748 extensionsString.append(patterns[idx]);
750 return extensionsString.toString();