Move ModulePointerManagerImpl to projectModel-impl
[idea/community.git] / plugins / ui-designer / src / com / intellij / uiDesigner / StringDescriptorManager.java
1 /*
2  * Copyright 2000-2009 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
17 package com.intellij.uiDesigner;
18
19 import com.intellij.lang.properties.IProperty;
20 import com.intellij.lang.properties.PropertiesUtil;
21 import com.intellij.lang.properties.psi.PropertiesFile;
22 import com.intellij.openapi.module.Module;
23 import com.intellij.openapi.module.ModuleServiceManager;
24 import com.intellij.openapi.roots.ModuleRootAdapter;
25 import com.intellij.openapi.util.Pair;
26 import com.intellij.openapi.roots.ModuleRootEvent;
27 import com.intellij.reference.SoftReference;
28 import com.intellij.uiDesigner.lw.StringDescriptor;
29 import com.intellij.uiDesigner.radComponents.RadComponent;
30 import com.intellij.uiDesigner.radComponents.RadRootContainer;
31 import com.intellij.util.messages.MessageBus;
32 import com.intellij.ProjectTopics;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
35
36 import java.util.HashMap;
37 import java.util.Locale;
38 import java.util.Map;
39
40 /**
41  * @author yole
42  */
43 public class StringDescriptorManager {
44   private final Module myModule;
45   private final Map<Pair<Locale, String>, SoftReference<PropertiesFile>> myPropertiesFileCache = new HashMap<Pair<Locale, String>, SoftReference<PropertiesFile>>();
46
47   public StringDescriptorManager(final Module module, MessageBus bus) {
48     myModule = module;
49     bus.connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
50       public void rootsChanged(final ModuleRootEvent event) {
51         synchronized(myPropertiesFileCache) {
52           myPropertiesFileCache.clear();
53         }
54       }
55     });
56   }
57
58   public static StringDescriptorManager getInstance(Module module) {
59     return ModuleServiceManager.getService(module, StringDescriptorManager.class);
60   }
61
62   @Nullable public String resolve(@NotNull RadComponent component, @Nullable StringDescriptor descriptor) {
63     RadRootContainer root = (RadRootContainer) FormEditingUtil.getRoot(component);
64     Locale locale = (root != null) ? root.getStringDescriptorLocale() : null;
65     return resolve(descriptor, locale);
66   }
67
68   @Nullable public String resolve(@Nullable StringDescriptor descriptor, @Nullable Locale locale) {
69     if (descriptor == null) {
70       return null;
71     }
72
73     if (descriptor.getValue() != null) {
74       return descriptor.getValue();
75     }
76
77     IProperty prop = resolveToProperty(descriptor, locale);
78     if (prop != null) {
79       final String value = prop.getUnescapedValue();
80       if (value != null) {
81         return value;
82       }
83     }
84     // We have to return surrogate string in case if propFile name is invalid or bundle doesn't have specified key
85     return "[" + descriptor.getKey() + " / " + descriptor.getBundleName() + "]";
86   }
87
88   public IProperty resolveToProperty(@NotNull StringDescriptor descriptor, @Nullable Locale locale) {
89     String propFileName = descriptor.getDottedBundleName();
90     Pair<Locale, String> cacheKey = new Pair<Locale, String>(locale, propFileName);
91     SoftReference<PropertiesFile> propertiesFileRef;
92     synchronized (myPropertiesFileCache) {
93       propertiesFileRef = myPropertiesFileCache.get(cacheKey);
94     }
95     PropertiesFile propertiesFile = (propertiesFileRef == null) ? null : propertiesFileRef.get();
96     if (propertiesFile == null || !propertiesFile.getContainingFile().isValid()) {
97       propertiesFile = PropertiesUtil.getPropertiesFile(propFileName, myModule, locale);
98       synchronized (myPropertiesFileCache) {
99         myPropertiesFileCache.put(cacheKey, new SoftReference<PropertiesFile>(propertiesFile));
100       }
101     }
102
103     if (propertiesFile != null) {
104       final IProperty propertyByKey = propertiesFile.findPropertyByKey(descriptor.getKey());
105       if (propertyByKey != null) {
106         return propertyByKey;
107       }
108     }
109     return null;
110   }
111 }