jps model: cache role instances to optimize memory usage
[idea/community.git] / jps / model-impl / src / org / jetbrains / jps / model / module / impl / JpsSdkReferencesTableImpl.java
1 /*
2  * Copyright 2000-2012 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 package org.jetbrains.jps.model.module.impl;
17
18 import com.intellij.util.containers.ContainerUtil;
19 import org.jetbrains.annotations.NotNull;
20 import org.jetbrains.annotations.Nullable;
21 import org.jetbrains.jps.model.JpsElement;
22 import org.jetbrains.jps.model.JpsElementCreator;
23 import org.jetbrains.jps.model.ex.JpsCompositeElementBase;
24 import org.jetbrains.jps.model.ex.JpsElementChildRoleBase;
25 import org.jetbrains.jps.model.library.sdk.JpsSdkReference;
26 import org.jetbrains.jps.model.library.sdk.JpsSdkType;
27 import org.jetbrains.jps.model.module.JpsSdkReferencesTable;
28
29 import java.util.concurrent.ConcurrentMap;
30
31 /**
32  * @author nik
33  */
34 public class JpsSdkReferencesTableImpl extends JpsCompositeElementBase<JpsSdkReferencesTableImpl> implements JpsSdkReferencesTable {
35   public static final JpsSdkReferencesTableRole ROLE = new JpsSdkReferencesTableRole();
36   private static final ConcurrentMap<JpsSdkType, JpsSdkReferenceRole> ourReferenceRoles = ContainerUtil.newConcurrentMap();
37
38   public JpsSdkReferencesTableImpl() {
39     super();
40   }
41
42   private JpsSdkReferencesTableImpl(JpsSdkReferencesTableImpl original) {
43     super(original);
44   }
45
46   @NotNull
47   @Override
48   public JpsSdkReferencesTableImpl createCopy() {
49     return new JpsSdkReferencesTableImpl(this);
50   }
51
52   @Override
53   public <P extends JpsElement> void setSdkReference(@NotNull JpsSdkType<P> type, @Nullable JpsSdkReference<P> sdkReference) {
54     JpsSdkReferenceRole<P> role = getSdkReferenceRole(type);
55     if (sdkReference != null) {
56       myContainer.setChild(role, sdkReference);
57     }
58     else {
59       myContainer.removeChild(role);
60     }
61   }
62
63   @Override
64   public <P extends JpsElement> JpsSdkReference<P> getSdkReference(@NotNull JpsSdkType<P> type) {
65     return myContainer.getChild(getSdkReferenceRole(type));
66   }
67
68   @SuppressWarnings("unchecked")
69   @NotNull
70   private static <P extends JpsElement> JpsSdkReferenceRole<P> getSdkReferenceRole(@NotNull JpsSdkType<P> type) {
71     JpsSdkReferenceRole<P> role = ourReferenceRoles.get(type);
72     if (role != null) return role;
73     ourReferenceRoles.putIfAbsent(type, new JpsSdkReferenceRole<P>(type));
74     return ourReferenceRoles.get(type);
75   }
76
77   private static class JpsSdkReferencesTableRole extends JpsElementChildRoleBase<JpsSdkReferencesTable> implements JpsElementCreator<JpsSdkReferencesTable> {
78     public JpsSdkReferencesTableRole() {
79       super("sdk references");
80     }
81
82     @NotNull
83     @Override
84     public JpsSdkReferencesTable create() {
85       return new JpsSdkReferencesTableImpl();
86     }
87   }
88 }