PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/netbeans-7.3/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/content/project/DeclarationContainer.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 355 lines | 272 code | 23 blank | 60 comment | 46 complexity | c1341cfc795da91b71fc6eb25ee1720a MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.cnd.modelimpl.content.project;
  45. import java.io.IOException;
  46. import java.util.ArrayList;
  47. import java.util.Arrays;
  48. import java.util.Collection;
  49. import java.util.Map;
  50. import java.util.SortedMap;
  51. import java.util.TreeMap;
  52. import java.util.concurrent.locks.ReadWriteLock;
  53. import java.util.concurrent.locks.ReentrantReadWriteLock;
  54. import org.netbeans.modules.cnd.api.model.CsmDeclaration;
  55. import org.netbeans.modules.cnd.api.model.CsmDeclaration.Kind;
  56. import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration;
  57. import org.netbeans.modules.cnd.api.model.CsmUID;
  58. import org.netbeans.modules.cnd.modelimpl.csm.ForwardClass;
  59. import org.netbeans.modules.cnd.modelimpl.csm.ForwardEnum;
  60. import org.netbeans.modules.cnd.modelimpl.csm.core.OffsetableDeclarationBase;
  61. import org.netbeans.modules.cnd.modelimpl.csm.core.Utils;
  62. import org.netbeans.modules.cnd.modelimpl.debug.DiagnosticExceptoins;
  63. import org.netbeans.modules.cnd.modelimpl.repository.RepositoryUtils;
  64. import org.netbeans.modules.cnd.modelimpl.uid.UIDCsmConverter;
  65. import org.netbeans.modules.cnd.modelimpl.uid.UIDObjectFactory;
  66. import org.netbeans.modules.cnd.repository.spi.Persistent;
  67. import org.netbeans.modules.cnd.repository.support.SelfPersistent;
  68. import org.openide.util.CharSequences;
  69. import org.netbeans.modules.cnd.modelimpl.textcache.UniqueNameCache;
  70. import org.netbeans.modules.cnd.modelimpl.uid.UIDUtilities;
  71. import org.netbeans.modules.cnd.repository.spi.Key;
  72. import org.netbeans.modules.cnd.repository.spi.RepositoryDataInput;
  73. import org.netbeans.modules.cnd.repository.spi.RepositoryDataOutput;
  74. /**
  75. * Storage for project or namespace declarations.
  76. * @author Alexander Simon
  77. */
  78. public abstract class DeclarationContainer extends ProjectComponent implements Persistent, SelfPersistent {
  79. private final TreeMap<CharSequence, Object> declarations;
  80. private final ReadWriteLock declarationsLock = new ReentrantReadWriteLock();
  81. protected DeclarationContainer(Key key) {
  82. super(key);
  83. declarations = new TreeMap<CharSequence, Object>(CharSequences.comparator());
  84. }
  85. protected DeclarationContainer(RepositoryDataInput input) throws IOException {
  86. super(input);
  87. declarations = UIDObjectFactory.getDefaultFactory().readStringToArrayUIDMap(input, UniqueNameCache.getManager());
  88. }
  89. public void removeDeclaration(CsmOffsetableDeclaration decl) {
  90. CharSequence uniqueName = CharSequences.create(decl.getUniqueName());
  91. CsmUID<CsmOffsetableDeclaration> anUid = UIDCsmConverter.declarationToUID(decl);
  92. Object o = null;
  93. try {
  94. declarationsLock.writeLock().lock();
  95. o = declarations.get(uniqueName);
  96. if (o instanceof CsmUID<?>[]) {
  97. @SuppressWarnings("unchecked")
  98. CsmUID<CsmOffsetableDeclaration>[] uids = (CsmUID<CsmOffsetableDeclaration>[]) o;
  99. int size = uids.length;
  100. CsmUID<CsmOffsetableDeclaration> res = null;
  101. int k = size;
  102. for (int i = 0; i < size; i++) {
  103. CsmUID<CsmOffsetableDeclaration> uid = uids[i];
  104. if (anUid.equals(uid)) {
  105. uids[i] = null;
  106. k--;
  107. } else {
  108. res = uid;
  109. }
  110. }
  111. if (k == 0) {
  112. declarations.remove(uniqueName);
  113. } else if (k == 1) {
  114. declarations.put(uniqueName, res);
  115. } else {
  116. @SuppressWarnings("unchecked")
  117. CsmUID<CsmOffsetableDeclaration>[] newUids = new CsmUID[k];
  118. k = 0;
  119. for (int i = 0; i < size; i++) {
  120. CsmUID<CsmOffsetableDeclaration> uid = uids[i];
  121. if (uid != null) {
  122. newUids[k] = uid;
  123. k++;
  124. }
  125. }
  126. declarations.put(uniqueName, newUids);
  127. }
  128. } else if (o instanceof CsmUID<?>) {
  129. declarations.remove(uniqueName);
  130. }
  131. } finally {
  132. declarationsLock.writeLock().unlock();
  133. }
  134. onRemoveDeclaration(decl);
  135. put();
  136. }
  137. protected void onRemoveDeclaration(CsmOffsetableDeclaration decl) {
  138. }
  139. protected ReadWriteLock getLock() {
  140. return declarationsLock;
  141. }
  142. public void putDeclaration(CsmOffsetableDeclaration decl) {
  143. CharSequence name = UniqueNameCache.getManager().getString(decl.getUniqueName());
  144. CsmUID<CsmOffsetableDeclaration> uid = RepositoryUtils.put(decl);
  145. assert uid != null;
  146. if (!(uid instanceof SelfPersistent)) {
  147. String line = " ["+decl.getStartPosition().getLine()+":"+decl.getStartPosition().getColumn()+"-"+ // NOI18N
  148. decl.getEndPosition().getLine()+":"+decl.getEndPosition().getColumn()+"]"; // NOI18N
  149. new Exception("attempt to put local declaration " + decl + line).printStackTrace(); // NOI18N
  150. }
  151. try {
  152. declarationsLock.writeLock().lock();
  153. Object o = declarations.get(name);
  154. // there could be at max only one forward class and
  155. // we don't want forward class to overwrite anything
  156. if (o != null && (ForwardClass.isForwardClass(decl) || ForwardEnum.isForwardEnum(decl))) {
  157. return;
  158. }
  159. if (o instanceof CsmUID<?>[]) {
  160. @SuppressWarnings("unchecked")
  161. CsmUID<CsmOffsetableDeclaration>[] uids = (CsmUID[]) o;
  162. boolean found = false;
  163. for (int i = 0; i < uids.length; i++) {
  164. if (UIDUtilities.isSameFile(uids[i], uid) || UIDUtilities.isForwardClass(uids[i])) {
  165. uids[i] = uid;
  166. found = true;
  167. break;
  168. }
  169. }
  170. if (!found) {
  171. @SuppressWarnings("unchecked")
  172. CsmUID<CsmOffsetableDeclaration>[] res = new CsmUID[uids.length + 1];
  173. res[0] = uid;
  174. System.arraycopy(uids, 0, res, 1, uids.length);
  175. declarations.put(name, res);
  176. }
  177. } else if (o instanceof CsmUID<?>) {
  178. @SuppressWarnings("unchecked")
  179. CsmUID<CsmOffsetableDeclaration> oldUid = (CsmUID<CsmOffsetableDeclaration>) o;
  180. if (UIDUtilities.isSameFile(oldUid, uid) || UIDUtilities.isForwardClass(oldUid)) {
  181. declarations.put(name, uid);
  182. } else {
  183. CsmUID<?>[] uids = new CsmUID<?>[]{uid, oldUid};
  184. declarations.put(name, uids);
  185. }
  186. } else {
  187. declarations.put(name, uid);
  188. }
  189. } finally {
  190. declarationsLock.writeLock().unlock();
  191. }
  192. onPutDeclaration(decl);
  193. put();
  194. }
  195. protected void onPutDeclaration(CsmOffsetableDeclaration decl) {
  196. }
  197. public Collection<CsmUID<CsmOffsetableDeclaration>> getUIDsRange(CharSequence from, CharSequence to) {
  198. Collection<CsmUID<CsmOffsetableDeclaration>> list = new ArrayList<CsmUID<CsmOffsetableDeclaration>>();
  199. from = CharSequences.create(from);
  200. to = CharSequences.create(to);
  201. try {
  202. declarationsLock.readLock().lock();
  203. for (Map.Entry<CharSequence, Object> entry : declarations.subMap(from, to).entrySet()) {
  204. addAll(list, entry.getValue());
  205. }
  206. } finally {
  207. declarationsLock.readLock().unlock();
  208. }
  209. return list;
  210. }
  211. public Collection<CsmUID<CsmOffsetableDeclaration>> getUIDsFQN(CharSequence fqn, Kind[] kinds) {
  212. Collection<CsmUID<CsmOffsetableDeclaration>> list = new ArrayList<CsmUID<CsmOffsetableDeclaration>>();
  213. char maxChar = 255; //Character.MAX_VALUE;
  214. for(Kind kind : kinds) {
  215. String prefix = Utils.getCsmDeclarationKindkey(kind) + OffsetableDeclarationBase.UNIQUE_NAME_SEPARATOR + fqn;
  216. CharSequence from = CharSequences.create(prefix);
  217. CharSequence to = CharSequences.create(prefix+maxChar);
  218. try {
  219. declarationsLock.readLock().lock();
  220. for (Map.Entry<CharSequence, Object> entry : declarations.subMap(from, to).entrySet()) {
  221. addAll(list, entry.getValue());
  222. }
  223. } finally {
  224. declarationsLock.readLock().unlock();
  225. }
  226. }
  227. return list;
  228. }
  229. // for unit test
  230. public SortedMap<CharSequence, Object> getTestDeclarations() {
  231. try {
  232. declarationsLock.readLock().lock();
  233. return new TreeMap<CharSequence, Object>(declarations);
  234. } finally {
  235. declarationsLock.readLock().unlock();
  236. }
  237. }
  238. /**
  239. * Adds ether object to the collection or array of objects
  240. * @param list
  241. * @param o - can be CsmUID or CsmUID[]
  242. */
  243. private static void addAll(Collection<CsmUID<CsmOffsetableDeclaration>> list, Object o) {
  244. if (o instanceof CsmUID<?>[]) {
  245. // we know the template type to be CsmOffsetableDeclaration
  246. @SuppressWarnings("unchecked") // checked
  247. final CsmUID<CsmOffsetableDeclaration>[] uids = (CsmUID<CsmOffsetableDeclaration>[]) o;
  248. list.addAll(Arrays.asList(uids));
  249. } else if (o instanceof CsmUID<?>) {
  250. // we know the template type to be CsmOffsetableDeclaration
  251. @SuppressWarnings("unchecked") // checked
  252. final CsmUID<CsmOffsetableDeclaration> uid = (CsmUID<CsmOffsetableDeclaration>) o;
  253. list.add(uid);
  254. }
  255. }
  256. public Collection<CsmOffsetableDeclaration> getDeclarationsRange(CharSequence from, CharSequence to) {
  257. return UIDCsmConverter.UIDsToDeclarations(getUIDsRange(from, to));
  258. }
  259. public Collection<CsmOffsetableDeclaration> getDeclarationsRange(CharSequence fqn, Kind[] kinds) {
  260. return UIDCsmConverter.UIDsToDeclarations(getUIDsFQN(fqn, kinds));
  261. }
  262. public Collection<CsmUID<CsmOffsetableDeclaration>> getDeclarationsUIDs() {
  263. // add all declarations
  264. Collection<CsmUID<CsmOffsetableDeclaration>> list = new ArrayList<CsmUID<CsmOffsetableDeclaration>>();
  265. try {
  266. declarationsLock.readLock().lock();
  267. for (Object o : declarations.values()) {
  268. addAll(list, o);
  269. }
  270. } finally {
  271. declarationsLock.readLock().unlock();
  272. }
  273. return list;
  274. }
  275. public Collection<CsmOffsetableDeclaration> findDeclarations(CharSequence uniqueName) {
  276. Collection<CsmUID<CsmOffsetableDeclaration>> list = new ArrayList<CsmUID<CsmOffsetableDeclaration>>();
  277. uniqueName = CharSequences.create(uniqueName);
  278. try {
  279. declarationsLock.readLock().lock();
  280. addAll(list, declarations.get(uniqueName));
  281. } finally {
  282. declarationsLock.readLock().unlock();
  283. }
  284. return UIDCsmConverter.UIDsToDeclarations(list);
  285. }
  286. public CsmDeclaration getDeclaration(CharSequence uniqueName) {
  287. CsmDeclaration result;
  288. CsmUID<CsmDeclaration> uid = null;
  289. uniqueName = CharSequences.create(uniqueName);
  290. try {
  291. declarationsLock.readLock().lock();
  292. Object o = declarations.get(uniqueName);
  293. if (o instanceof CsmUID<?>[]) {
  294. // we know the template type to be CsmDeclaration
  295. @SuppressWarnings("unchecked") // checked
  296. final CsmUID<CsmDeclaration>[] uids = (CsmUID<CsmDeclaration>[]) o;
  297. uid = uids[0];
  298. } else if (o instanceof CsmUID<?>) {
  299. // we know the template type to be CsmDeclaration
  300. @SuppressWarnings("unchecked") // checked
  301. final CsmUID<CsmDeclaration> uidt = (CsmUID<CsmDeclaration>) o;
  302. uid = uidt;
  303. }
  304. } finally {
  305. declarationsLock.readLock().unlock();
  306. }
  307. result = UIDCsmConverter.UIDtoDeclaration(uid);
  308. if (uid != null && result == null) {
  309. DiagnosticExceptoins.registerIllegalRepositoryStateException("no declaration for UID ", uid); // NOI18N
  310. }
  311. return result;
  312. }
  313. public void clearDeclarations() {
  314. try {
  315. declarationsLock.writeLock().lock();
  316. declarations.clear();
  317. put();
  318. } finally {
  319. declarationsLock.writeLock().unlock();
  320. }
  321. }
  322. @Override
  323. public void write(RepositoryDataOutput aStream) throws IOException {
  324. super.write(aStream);
  325. try {
  326. declarationsLock.readLock().lock();
  327. UIDObjectFactory.getDefaultFactory().writeStringToArrayUIDMap(declarations, aStream, false);
  328. } finally {
  329. declarationsLock.readLock().unlock();
  330. }
  331. }
  332. }