PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 401 lines | 320 code | 20 blank | 61 comment | 47 complexity | 6006c0f545757a54fb3229d3289da04c MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 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. * If you wish your version of this file to be governed by only the CDDL
  28. * or only the GPL Version 2, indicate your decision by adding
  29. * "[Contributor] elects to include this software in this distribution
  30. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  31. * single choice of license, a recipient has the option to distribute
  32. * your version of this file under either the CDDL, the GPL Version 2 or
  33. * to extend the choice of license to its licensees as provided above.
  34. * However, if you add GPL Version 2 code and therefore, elected the GPL
  35. * Version 2 license, then the option applies only if the new code is
  36. * made subject to such option by the copyright holder.
  37. *
  38. * Contributor(s):
  39. *
  40. * Portions Copyrighted 2010 Sun Microsystems, Inc.
  41. */
  42. package org.netbeans.modules.cnd.modelimpl.content.project;
  43. import java.io.IOException;
  44. import java.util.ArrayList;
  45. import java.util.Collection;
  46. import java.util.Collections;
  47. import java.util.HashMap;
  48. import java.util.HashSet;
  49. import java.util.List;
  50. import java.util.Map;
  51. import java.util.Set;
  52. import java.util.SortedMap;
  53. import java.util.TreeMap;
  54. import java.util.concurrent.ConcurrentHashMap;
  55. import java.util.concurrent.locks.ReadWriteLock;
  56. import java.util.concurrent.locks.ReentrantReadWriteLock;
  57. import org.netbeans.modules.cnd.api.model.CsmClass;
  58. import org.netbeans.modules.cnd.api.model.CsmDeclaration;
  59. import org.netbeans.modules.cnd.api.model.CsmFriend;
  60. import org.netbeans.modules.cnd.api.model.CsmFriendClass;
  61. import org.netbeans.modules.cnd.api.model.CsmFriendFunction;
  62. import org.netbeans.modules.cnd.api.model.CsmFunction;
  63. import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration;
  64. import org.netbeans.modules.cnd.api.model.CsmUID;
  65. import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities;
  66. import org.netbeans.modules.cnd.api.model.util.UIDs;
  67. import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage;
  68. import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage.DataPresentationImpl;
  69. import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage.KeyDataPresentationImpl;
  70. import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage.UniqueNameImpl;
  71. import org.netbeans.modules.cnd.modelimpl.csm.core.ProjectBase;
  72. import org.netbeans.modules.cnd.modelimpl.repository.ProjectDeclarationContainerKey;
  73. import org.netbeans.modules.cnd.modelimpl.repository.RepositoryUtils;
  74. import org.netbeans.modules.cnd.modelimpl.textcache.UniqueNameCache;
  75. import org.netbeans.modules.cnd.modelimpl.uid.UIDCsmConverter;
  76. import org.netbeans.modules.cnd.modelimpl.uid.UIDObjectFactory;
  77. import org.netbeans.modules.cnd.repository.api.RepositoryAccessor;
  78. import org.netbeans.modules.cnd.repository.spi.Key;
  79. import org.netbeans.modules.cnd.repository.spi.KeyDataPresentation;
  80. import org.netbeans.modules.cnd.repository.spi.MapBasedTable;
  81. import org.netbeans.modules.cnd.repository.spi.RepositoryDataInput;
  82. import org.netbeans.modules.cnd.repository.spi.RepositoryDataOutput;
  83. import org.netbeans.modules.cnd.repository.support.KeyPresentationFactorySupport;
  84. import org.openide.util.CharSequences;
  85. /**
  86. *
  87. * @author Alexander Simon
  88. */
  89. public class DeclarationContainerProject extends DeclarationContainer {
  90. private final ReadWriteLock friendsLock = new ReentrantReadWriteLock();
  91. private final Map<CharSequence, Set<CsmUID<CsmFriend>>> friends;
  92. private static final boolean TEST_DATABASE = false;
  93. private static final DeclarationContainerProject EMPTY = new DeclarationContainerProject() {
  94. @Override
  95. public void put() {
  96. }
  97. @Override
  98. public void putDeclaration(CsmOffsetableDeclaration decl) {
  99. }
  100. };
  101. public DeclarationContainerProject(ProjectBase project) {
  102. super(new ProjectDeclarationContainerKey(project.getUnitId()));
  103. friends = new HashMap<CharSequence, Set<CsmUID<CsmFriend>>>();
  104. put();
  105. }
  106. public DeclarationContainerProject(RepositoryDataInput input) throws IOException {
  107. super(input);
  108. int colSize = input.readInt();
  109. friends = new HashMap<CharSequence, Set<CsmUID<CsmFriend>>>(colSize);
  110. UIDObjectFactory.getDefaultFactory().readStringToUIDMapSet(friends, input, UniqueNameCache.getManager(), colSize);
  111. }
  112. // only for EMPTY static field
  113. private DeclarationContainerProject() {
  114. super((Key) null);
  115. friends = new ConcurrentHashMap<CharSequence, Set<CsmUID<CsmFriend>>>();
  116. }
  117. public static DeclarationContainerProject empty() {
  118. return EMPTY;
  119. }
  120. @Override
  121. protected void onRemoveDeclaration(CsmOffsetableDeclaration decl) {
  122. if (CsmKindUtilities.isFriendClass(decl)) {
  123. CsmFriend cls = (CsmFriend) decl;
  124. CharSequence name = CharSequences.create(cls.getName());
  125. try {
  126. friendsLock.writeLock().lock();
  127. Set<CsmUID<CsmFriend>> set = friends.get(name);
  128. if (set != null) {
  129. set.remove(UIDs.get(cls));
  130. if (set.isEmpty()) {
  131. friends.remove(name);
  132. }
  133. }
  134. } finally {
  135. friendsLock.writeLock().unlock();
  136. }
  137. } else if (CsmKindUtilities.isFriendMethod(decl)) {
  138. CsmFriend fun = (CsmFriend) decl;
  139. CharSequence name = CharSequences.create(((CsmFriendFunction)fun).getSignature());
  140. try {
  141. friendsLock.writeLock().lock();
  142. Set<CsmUID<CsmFriend>> set = friends.get(name);
  143. if (set != null) {
  144. set.remove(UIDs.get(fun));
  145. if (set.isEmpty()) {
  146. friends.remove(name);
  147. }
  148. }
  149. } finally {
  150. friendsLock.writeLock().unlock();
  151. }
  152. }
  153. }
  154. @Override
  155. public void removeDeclaration(CsmOffsetableDeclaration decl) {
  156. super.removeDeclaration(decl);
  157. if (TEST_DATABASE) {
  158. CsmUID<CsmOffsetableDeclaration> uid = UIDCsmConverter.declarationToUID(decl);
  159. Key key = RepositoryUtils.UIDtoKey(uid);
  160. @SuppressWarnings("unchecked")
  161. MapBasedTable table = (MapBasedTable) RepositoryAccessor.getRepository().getDatabaseTable(key, DeclarationContainerProjectStorage.TABLE_NAME);
  162. KeyDataPresentation dataPresentation = key.getDataPresentation();
  163. KeyDataPresentationImpl keyImpl = new KeyDataPresentationImpl(
  164. dataPresentation.getUnitPresentation(), dataPresentation.getNamePresentation(),
  165. dataPresentation.getKindPresentation(), dataPresentation.getFilePresentation(),
  166. dataPresentation.getStartPresentation(), dataPresentation.getEndPresentation());
  167. try {
  168. getLock().writeLock().lock();
  169. DataPresentationImpl removedKeyImpl = (DataPresentationImpl) table.remove(keyImpl);
  170. // CharSequence uin = decl.getUniqueName();
  171. // UniqueNameImpl uinImpl = new UniqueNameImpl(uin);
  172. // DataPresentationImpl valueImpl = new DataPresentationImpl(keyImpl,uinImpl);
  173. // if (!valueImpl.equals(removedKeyImpl)) {
  174. // if (removedKeyImpl == null) {
  175. // new Exception("Declaration is not found in database\n"+
  176. // "\tDeclaration="+decl+"\n"+
  177. // "\tUIN="+uinImpl.getUin()).printStackTrace();
  178. // } else {
  179. // new Exception("Remove declaration with changed UIN\n"+
  180. // "\tDeclaration="+decl+"\n"+
  181. // "\tOld UIN="+removedKeyImpl.getUin()+"\n"+
  182. // "\tNew UIN="+uinImpl.getUin()).printStackTrace();
  183. // }
  184. // }
  185. } finally {
  186. getLock().writeLock().unlock();
  187. }
  188. }
  189. }
  190. @Override
  191. public void putDeclaration(CsmOffsetableDeclaration decl) {
  192. super.putDeclaration(decl);
  193. if (TEST_DATABASE) {
  194. CharSequence uin = decl.getUniqueName();
  195. CsmUID<CsmOffsetableDeclaration> uid = UIDCsmConverter.declarationToUID(decl);
  196. Key key = RepositoryUtils.UIDtoKey(uid);
  197. @SuppressWarnings("unchecked")
  198. MapBasedTable table = (MapBasedTable) RepositoryAccessor.getRepository().getDatabaseTable(key, DeclarationContainerProjectStorage.TABLE_NAME);
  199. KeyDataPresentation dataPresentation = key.getDataPresentation();
  200. KeyDataPresentationImpl keyImpl = new KeyDataPresentationImpl(
  201. dataPresentation.getUnitPresentation(), dataPresentation.getNamePresentation(),
  202. dataPresentation.getKindPresentation(), dataPresentation.getFilePresentation(),
  203. dataPresentation.getStartPresentation(), dataPresentation.getEndPresentation());
  204. UniqueNameImpl uinImpl = new UniqueNameImpl(uin);
  205. DataPresentationImpl valueImpl = new DataPresentationImpl(keyImpl,uinImpl);
  206. try {
  207. getLock().writeLock().lock();
  208. table.put(keyImpl, valueImpl);
  209. } finally {
  210. getLock().writeLock().unlock();
  211. }
  212. try {
  213. getLock().readLock().lock();
  214. assert table.get(keyImpl).equals(valueImpl);
  215. } finally {
  216. getLock().readLock().unlock();
  217. }
  218. }
  219. }
  220. @Override
  221. public Collection<CsmOffsetableDeclaration> findDeclarations(CharSequence uniqueName) {
  222. Collection<CsmOffsetableDeclaration> res = super.findDeclarations(uniqueName);
  223. if (TEST_DATABASE) {
  224. UniqueNameImpl uinImpl = new UniqueNameImpl(uniqueName);
  225. Collection<DataPresentationImpl> res2 = new ArrayList<DataPresentationImpl>();
  226. try {
  227. getLock().readLock().lock();
  228. @SuppressWarnings("unchecked")
  229. Collection<DataPresentationImpl> index = (Collection<DataPresentationImpl>)
  230. ((MapBasedTable)RepositoryAccessor.getRepository().getDatabaseTable(getKey(), DeclarationContainerProjectStorage.TABLE_INDEX)).duplicates(uinImpl);
  231. res2.addAll(index);
  232. } finally {
  233. getLock().readLock().unlock();
  234. }
  235. Collection<CsmOffsetableDeclaration> res3 = new ArrayList<CsmOffsetableDeclaration>();
  236. for (DataPresentationImpl entry : res2){
  237. Key aKey = KeyPresentationFactorySupport.create(entry);
  238. CsmOffsetableDeclaration decl = (CsmOffsetableDeclaration) RepositoryAccessor.getRepository().get(aKey);
  239. res3.add(decl);
  240. }
  241. if (res.size() != res3.size()) {
  242. System.err.println("Find gets different results");
  243. System.err.println("Map:");
  244. for(CsmOffsetableDeclaration decl : res) {
  245. System.err.println("\t"+decl);
  246. }
  247. System.err.println("Database:");
  248. for(CsmOffsetableDeclaration decl : res3) {
  249. System.err.println("\t"+decl);
  250. }
  251. }
  252. return res3;
  253. }
  254. return res;
  255. }
  256. @Override
  257. public CsmDeclaration getDeclaration(CharSequence uniqueName) {
  258. CsmDeclaration res = super.getDeclaration(uniqueName);
  259. if (TEST_DATABASE) {
  260. UniqueNameImpl uinImpl = new UniqueNameImpl(uniqueName);
  261. DataPresentationImpl res2;
  262. try {
  263. getLock().readLock().lock();
  264. res2 = (DataPresentationImpl)
  265. ((MapBasedTable)RepositoryAccessor.getRepository().getDatabaseTable(getKey(), DeclarationContainerProjectStorage.TABLE_INDEX)).get(uinImpl);
  266. } finally {
  267. getLock().readLock().unlock();
  268. }
  269. CsmOffsetableDeclaration res3 = null;
  270. if (res2 != null) {
  271. Key aKey = KeyPresentationFactorySupport.create(res2);
  272. res3 = (CsmOffsetableDeclaration) RepositoryAccessor.getRepository().get(aKey);
  273. }
  274. if (res != null && res3 != null && !res.equals(res3)) {
  275. System.err.println("Find gets different results");
  276. System.err.println("Map:");
  277. System.err.println("\t"+res);
  278. System.err.println("Database:");
  279. System.err.println("\t"+res3);
  280. }
  281. return res3;
  282. }
  283. return res;
  284. }
  285. @Override
  286. protected void onPutDeclaration(CsmOffsetableDeclaration decl) {
  287. if (CsmKindUtilities.isFriendClass(decl)) {
  288. CsmFriend cls = (CsmFriend) decl;
  289. CharSequence name = CharSequences.create(cls.getName());
  290. try {
  291. friendsLock.writeLock().lock();
  292. Set<CsmUID<CsmFriend>> set = friends.get(name);
  293. if (set == null) {
  294. set = new HashSet<CsmUID<CsmFriend>>();
  295. friends.put(name, set);
  296. }
  297. set.add(UIDs.get(cls));
  298. } finally {
  299. friendsLock.writeLock().unlock();
  300. }
  301. } else if (CsmKindUtilities.isFriendMethod(decl)) {
  302. CsmFriend fun = (CsmFriend) decl;
  303. CharSequence name = CharSequences.create(((CsmFriendFunction)fun).getSignature());
  304. try {
  305. friendsLock.writeLock().lock();
  306. Set<CsmUID<CsmFriend>> set = friends.get(name);
  307. if (set == null) {
  308. set = new HashSet<CsmUID<CsmFriend>>();
  309. friends.put(name, set);
  310. }
  311. set.add(UIDs.get(fun));
  312. } finally {
  313. friendsLock.writeLock().unlock();
  314. }
  315. }
  316. }
  317. public SortedMap<CharSequence, Set<CsmUID<CsmFriend>>> getTestFriends(){
  318. try {
  319. friendsLock.readLock().lock();
  320. TreeMap<CharSequence, Set<CsmUID<CsmFriend>>> res = new TreeMap<CharSequence, Set<CsmUID<CsmFriend>>>();
  321. for(Map.Entry<CharSequence, Set<CsmUID<CsmFriend>>> entry : friends.entrySet()) {
  322. res.put(entry.getKey(), new HashSet<CsmUID<CsmFriend>>(entry.getValue()));
  323. }
  324. return res;
  325. } finally {
  326. friendsLock.readLock().unlock();
  327. }
  328. }
  329. public Collection<CsmFriend> findFriends(CsmOffsetableDeclaration decl) {
  330. CharSequence name = null;
  331. if (CsmKindUtilities.isClass(decl)) {
  332. CsmClass cls = (CsmClass) decl;
  333. name = cls.getName();
  334. } else if (CsmKindUtilities.isFunction(decl)) {
  335. CsmFunction fun = (CsmFunction) decl;
  336. name = fun.getSignature();
  337. }
  338. if (name != null) {
  339. name = CharSequences.create(name);
  340. List<CsmUID<? extends CsmFriend>> list = new ArrayList<CsmUID<? extends CsmFriend>>();
  341. try {
  342. friendsLock.readLock().lock();
  343. Set<CsmUID<CsmFriend>> set = friends.get(name);
  344. if (set != null) {
  345. list.addAll(set);
  346. }
  347. } finally {
  348. friendsLock.readLock().unlock();
  349. }
  350. if (list.size() > 0) {
  351. Collection<CsmFriend> res = new ArrayList<CsmFriend>();
  352. for (CsmUID<? extends CsmFriend> friendUID : list) {
  353. CsmFriend friend = friendUID.getObject();
  354. if (CsmKindUtilities.isFriendClass(friend)) {
  355. CsmFriendClass cls = (CsmFriendClass) friend;
  356. if (decl.equals(cls.getReferencedClass())) {
  357. res.add(cls);
  358. }
  359. } else if (CsmKindUtilities.isFriendMethod(friend)) {
  360. CsmFriendFunction fun = (CsmFriendFunction) friend;
  361. if (decl.equals(fun.getReferencedFunction())) {
  362. res.add(fun);
  363. }
  364. }
  365. }
  366. return res;
  367. }
  368. }
  369. return Collections.<CsmFriend>emptyList();
  370. }
  371. @Override
  372. public void write(RepositoryDataOutput aStream) throws IOException {
  373. super.write(aStream);
  374. try {
  375. friendsLock.readLock().lock();
  376. UIDObjectFactory.getDefaultFactory().writeStringToUIDMapSet(friends, aStream);
  377. } finally {
  378. friendsLock.readLock().unlock();
  379. }
  380. }
  381. }