/projects/netbeans-7.3/cnd.modelimpl/src/org/netbeans/modules/cnd/modelimpl/content/project/DeclarationContainerProject.java
Java | 401 lines | 320 code | 20 blank | 61 comment | 47 complexity | 6006c0f545757a54fb3229d3289da04c MD5 | raw file
- /*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
- *
- * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
- * Other names may be trademarks of their respective owners.
- *
- * The contents of this file are subject to the terms of either the GNU
- * General Public License Version 2 only ("GPL") or the Common
- * Development and Distribution License("CDDL") (collectively, the
- * "License"). You may not use this file except in compliance with the
- * License. You can obtain a copy of the License at
- * http://www.netbeans.org/cddl-gplv2.html
- * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
- * specific language governing permissions and limitations under the
- * License. When distributing the software, include this License Header
- * Notice in each file and include the License file at
- * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the GPL Version 2 section of the License file that
- * accompanied this code. If applicable, add the following below the
- * License Header, with the fields enclosed by brackets [] replaced by
- * your own identifying information:
- * "Portions Copyrighted [year] [name of copyright owner]"
- *
- * If you wish your version of this file to be governed by only the CDDL
- * or only the GPL Version 2, indicate your decision by adding
- * "[Contributor] elects to include this software in this distribution
- * under the [CDDL or GPL Version 2] license." If you do not indicate a
- * single choice of license, a recipient has the option to distribute
- * your version of this file under either the CDDL, the GPL Version 2 or
- * to extend the choice of license to its licensees as provided above.
- * However, if you add GPL Version 2 code and therefore, elected the GPL
- * Version 2 license, then the option applies only if the new code is
- * made subject to such option by the copyright holder.
- *
- * Contributor(s):
- *
- * Portions Copyrighted 2010 Sun Microsystems, Inc.
- */
- package org.netbeans.modules.cnd.modelimpl.content.project;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.SortedMap;
- import java.util.TreeMap;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.locks.ReadWriteLock;
- import java.util.concurrent.locks.ReentrantReadWriteLock;
- import org.netbeans.modules.cnd.api.model.CsmClass;
- import org.netbeans.modules.cnd.api.model.CsmDeclaration;
- import org.netbeans.modules.cnd.api.model.CsmFriend;
- import org.netbeans.modules.cnd.api.model.CsmFriendClass;
- import org.netbeans.modules.cnd.api.model.CsmFriendFunction;
- import org.netbeans.modules.cnd.api.model.CsmFunction;
- import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration;
- import org.netbeans.modules.cnd.api.model.CsmUID;
- import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities;
- import org.netbeans.modules.cnd.api.model.util.UIDs;
- import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage;
- import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage.DataPresentationImpl;
- import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage.KeyDataPresentationImpl;
- import org.netbeans.modules.cnd.modelimpl.csm.core.DeclarationContainerProjectStorage.UniqueNameImpl;
- import org.netbeans.modules.cnd.modelimpl.csm.core.ProjectBase;
- import org.netbeans.modules.cnd.modelimpl.repository.ProjectDeclarationContainerKey;
- import org.netbeans.modules.cnd.modelimpl.repository.RepositoryUtils;
- import org.netbeans.modules.cnd.modelimpl.textcache.UniqueNameCache;
- import org.netbeans.modules.cnd.modelimpl.uid.UIDCsmConverter;
- import org.netbeans.modules.cnd.modelimpl.uid.UIDObjectFactory;
- import org.netbeans.modules.cnd.repository.api.RepositoryAccessor;
- import org.netbeans.modules.cnd.repository.spi.Key;
- import org.netbeans.modules.cnd.repository.spi.KeyDataPresentation;
- import org.netbeans.modules.cnd.repository.spi.MapBasedTable;
- import org.netbeans.modules.cnd.repository.spi.RepositoryDataInput;
- import org.netbeans.modules.cnd.repository.spi.RepositoryDataOutput;
- import org.netbeans.modules.cnd.repository.support.KeyPresentationFactorySupport;
- import org.openide.util.CharSequences;
- /**
- *
- * @author Alexander Simon
- */
- public class DeclarationContainerProject extends DeclarationContainer {
- private final ReadWriteLock friendsLock = new ReentrantReadWriteLock();
- private final Map<CharSequence, Set<CsmUID<CsmFriend>>> friends;
- private static final boolean TEST_DATABASE = false;
- private static final DeclarationContainerProject EMPTY = new DeclarationContainerProject() {
- @Override
- public void put() {
- }
- @Override
- public void putDeclaration(CsmOffsetableDeclaration decl) {
- }
- };
- public DeclarationContainerProject(ProjectBase project) {
- super(new ProjectDeclarationContainerKey(project.getUnitId()));
- friends = new HashMap<CharSequence, Set<CsmUID<CsmFriend>>>();
- put();
- }
- public DeclarationContainerProject(RepositoryDataInput input) throws IOException {
- super(input);
- int colSize = input.readInt();
- friends = new HashMap<CharSequence, Set<CsmUID<CsmFriend>>>(colSize);
- UIDObjectFactory.getDefaultFactory().readStringToUIDMapSet(friends, input, UniqueNameCache.getManager(), colSize);
- }
- // only for EMPTY static field
- private DeclarationContainerProject() {
- super((Key) null);
- friends = new ConcurrentHashMap<CharSequence, Set<CsmUID<CsmFriend>>>();
- }
- public static DeclarationContainerProject empty() {
- return EMPTY;
- }
- @Override
- protected void onRemoveDeclaration(CsmOffsetableDeclaration decl) {
- if (CsmKindUtilities.isFriendClass(decl)) {
- CsmFriend cls = (CsmFriend) decl;
- CharSequence name = CharSequences.create(cls.getName());
- try {
- friendsLock.writeLock().lock();
- Set<CsmUID<CsmFriend>> set = friends.get(name);
- if (set != null) {
- set.remove(UIDs.get(cls));
- if (set.isEmpty()) {
- friends.remove(name);
- }
- }
- } finally {
- friendsLock.writeLock().unlock();
- }
- } else if (CsmKindUtilities.isFriendMethod(decl)) {
- CsmFriend fun = (CsmFriend) decl;
- CharSequence name = CharSequences.create(((CsmFriendFunction)fun).getSignature());
- try {
- friendsLock.writeLock().lock();
- Set<CsmUID<CsmFriend>> set = friends.get(name);
- if (set != null) {
- set.remove(UIDs.get(fun));
- if (set.isEmpty()) {
- friends.remove(name);
- }
- }
- } finally {
- friendsLock.writeLock().unlock();
- }
- }
- }
- @Override
- public void removeDeclaration(CsmOffsetableDeclaration decl) {
- super.removeDeclaration(decl);
- if (TEST_DATABASE) {
- CsmUID<CsmOffsetableDeclaration> uid = UIDCsmConverter.declarationToUID(decl);
- Key key = RepositoryUtils.UIDtoKey(uid);
- @SuppressWarnings("unchecked")
- MapBasedTable table = (MapBasedTable) RepositoryAccessor.getRepository().getDatabaseTable(key, DeclarationContainerProjectStorage.TABLE_NAME);
- KeyDataPresentation dataPresentation = key.getDataPresentation();
- KeyDataPresentationImpl keyImpl = new KeyDataPresentationImpl(
- dataPresentation.getUnitPresentation(), dataPresentation.getNamePresentation(),
- dataPresentation.getKindPresentation(), dataPresentation.getFilePresentation(),
- dataPresentation.getStartPresentation(), dataPresentation.getEndPresentation());
- try {
- getLock().writeLock().lock();
- DataPresentationImpl removedKeyImpl = (DataPresentationImpl) table.remove(keyImpl);
- // CharSequence uin = decl.getUniqueName();
- // UniqueNameImpl uinImpl = new UniqueNameImpl(uin);
- // DataPresentationImpl valueImpl = new DataPresentationImpl(keyImpl,uinImpl);
- // if (!valueImpl.equals(removedKeyImpl)) {
- // if (removedKeyImpl == null) {
- // new Exception("Declaration is not found in database\n"+
- // "\tDeclaration="+decl+"\n"+
- // "\tUIN="+uinImpl.getUin()).printStackTrace();
- // } else {
- // new Exception("Remove declaration with changed UIN\n"+
- // "\tDeclaration="+decl+"\n"+
- // "\tOld UIN="+removedKeyImpl.getUin()+"\n"+
- // "\tNew UIN="+uinImpl.getUin()).printStackTrace();
- // }
- // }
- } finally {
- getLock().writeLock().unlock();
- }
- }
- }
- @Override
- public void putDeclaration(CsmOffsetableDeclaration decl) {
- super.putDeclaration(decl);
- if (TEST_DATABASE) {
- CharSequence uin = decl.getUniqueName();
- CsmUID<CsmOffsetableDeclaration> uid = UIDCsmConverter.declarationToUID(decl);
- Key key = RepositoryUtils.UIDtoKey(uid);
- @SuppressWarnings("unchecked")
- MapBasedTable table = (MapBasedTable) RepositoryAccessor.getRepository().getDatabaseTable(key, DeclarationContainerProjectStorage.TABLE_NAME);
- KeyDataPresentation dataPresentation = key.getDataPresentation();
- KeyDataPresentationImpl keyImpl = new KeyDataPresentationImpl(
- dataPresentation.getUnitPresentation(), dataPresentation.getNamePresentation(),
- dataPresentation.getKindPresentation(), dataPresentation.getFilePresentation(),
- dataPresentation.getStartPresentation(), dataPresentation.getEndPresentation());
- UniqueNameImpl uinImpl = new UniqueNameImpl(uin);
- DataPresentationImpl valueImpl = new DataPresentationImpl(keyImpl,uinImpl);
- try {
- getLock().writeLock().lock();
- table.put(keyImpl, valueImpl);
- } finally {
- getLock().writeLock().unlock();
- }
- try {
- getLock().readLock().lock();
- assert table.get(keyImpl).equals(valueImpl);
- } finally {
- getLock().readLock().unlock();
- }
- }
- }
- @Override
- public Collection<CsmOffsetableDeclaration> findDeclarations(CharSequence uniqueName) {
- Collection<CsmOffsetableDeclaration> res = super.findDeclarations(uniqueName);
- if (TEST_DATABASE) {
- UniqueNameImpl uinImpl = new UniqueNameImpl(uniqueName);
- Collection<DataPresentationImpl> res2 = new ArrayList<DataPresentationImpl>();
- try {
- getLock().readLock().lock();
- @SuppressWarnings("unchecked")
- Collection<DataPresentationImpl> index = (Collection<DataPresentationImpl>)
- ((MapBasedTable)RepositoryAccessor.getRepository().getDatabaseTable(getKey(), DeclarationContainerProjectStorage.TABLE_INDEX)).duplicates(uinImpl);
- res2.addAll(index);
- } finally {
- getLock().readLock().unlock();
- }
- Collection<CsmOffsetableDeclaration> res3 = new ArrayList<CsmOffsetableDeclaration>();
- for (DataPresentationImpl entry : res2){
- Key aKey = KeyPresentationFactorySupport.create(entry);
- CsmOffsetableDeclaration decl = (CsmOffsetableDeclaration) RepositoryAccessor.getRepository().get(aKey);
- res3.add(decl);
- }
- if (res.size() != res3.size()) {
- System.err.println("Find gets different results");
- System.err.println("Map:");
- for(CsmOffsetableDeclaration decl : res) {
- System.err.println("\t"+decl);
- }
- System.err.println("Database:");
- for(CsmOffsetableDeclaration decl : res3) {
- System.err.println("\t"+decl);
- }
- }
- return res3;
- }
- return res;
- }
- @Override
- public CsmDeclaration getDeclaration(CharSequence uniqueName) {
- CsmDeclaration res = super.getDeclaration(uniqueName);
- if (TEST_DATABASE) {
- UniqueNameImpl uinImpl = new UniqueNameImpl(uniqueName);
- DataPresentationImpl res2;
- try {
- getLock().readLock().lock();
- res2 = (DataPresentationImpl)
- ((MapBasedTable)RepositoryAccessor.getRepository().getDatabaseTable(getKey(), DeclarationContainerProjectStorage.TABLE_INDEX)).get(uinImpl);
- } finally {
- getLock().readLock().unlock();
- }
- CsmOffsetableDeclaration res3 = null;
- if (res2 != null) {
- Key aKey = KeyPresentationFactorySupport.create(res2);
- res3 = (CsmOffsetableDeclaration) RepositoryAccessor.getRepository().get(aKey);
- }
- if (res != null && res3 != null && !res.equals(res3)) {
- System.err.println("Find gets different results");
- System.err.println("Map:");
- System.err.println("\t"+res);
- System.err.println("Database:");
- System.err.println("\t"+res3);
- }
- return res3;
- }
- return res;
- }
- @Override
- protected void onPutDeclaration(CsmOffsetableDeclaration decl) {
- if (CsmKindUtilities.isFriendClass(decl)) {
- CsmFriend cls = (CsmFriend) decl;
- CharSequence name = CharSequences.create(cls.getName());
- try {
- friendsLock.writeLock().lock();
- Set<CsmUID<CsmFriend>> set = friends.get(name);
- if (set == null) {
- set = new HashSet<CsmUID<CsmFriend>>();
- friends.put(name, set);
- }
- set.add(UIDs.get(cls));
- } finally {
- friendsLock.writeLock().unlock();
- }
- } else if (CsmKindUtilities.isFriendMethod(decl)) {
- CsmFriend fun = (CsmFriend) decl;
- CharSequence name = CharSequences.create(((CsmFriendFunction)fun).getSignature());
- try {
- friendsLock.writeLock().lock();
- Set<CsmUID<CsmFriend>> set = friends.get(name);
- if (set == null) {
- set = new HashSet<CsmUID<CsmFriend>>();
- friends.put(name, set);
- }
- set.add(UIDs.get(fun));
- } finally {
- friendsLock.writeLock().unlock();
- }
- }
- }
- public SortedMap<CharSequence, Set<CsmUID<CsmFriend>>> getTestFriends(){
- try {
- friendsLock.readLock().lock();
- TreeMap<CharSequence, Set<CsmUID<CsmFriend>>> res = new TreeMap<CharSequence, Set<CsmUID<CsmFriend>>>();
- for(Map.Entry<CharSequence, Set<CsmUID<CsmFriend>>> entry : friends.entrySet()) {
- res.put(entry.getKey(), new HashSet<CsmUID<CsmFriend>>(entry.getValue()));
- }
- return res;
- } finally {
- friendsLock.readLock().unlock();
- }
- }
- public Collection<CsmFriend> findFriends(CsmOffsetableDeclaration decl) {
- CharSequence name = null;
- if (CsmKindUtilities.isClass(decl)) {
- CsmClass cls = (CsmClass) decl;
- name = cls.getName();
- } else if (CsmKindUtilities.isFunction(decl)) {
- CsmFunction fun = (CsmFunction) decl;
- name = fun.getSignature();
- }
- if (name != null) {
- name = CharSequences.create(name);
- List<CsmUID<? extends CsmFriend>> list = new ArrayList<CsmUID<? extends CsmFriend>>();
- try {
- friendsLock.readLock().lock();
- Set<CsmUID<CsmFriend>> set = friends.get(name);
- if (set != null) {
- list.addAll(set);
- }
- } finally {
- friendsLock.readLock().unlock();
- }
- if (list.size() > 0) {
- Collection<CsmFriend> res = new ArrayList<CsmFriend>();
- for (CsmUID<? extends CsmFriend> friendUID : list) {
- CsmFriend friend = friendUID.getObject();
- if (CsmKindUtilities.isFriendClass(friend)) {
- CsmFriendClass cls = (CsmFriendClass) friend;
- if (decl.equals(cls.getReferencedClass())) {
- res.add(cls);
- }
- } else if (CsmKindUtilities.isFriendMethod(friend)) {
- CsmFriendFunction fun = (CsmFriendFunction) friend;
- if (decl.equals(fun.getReferencedFunction())) {
- res.add(fun);
- }
- }
- }
- return res;
- }
- }
- return Collections.<CsmFriend>emptyList();
- }
- @Override
- public void write(RepositoryDataOutput aStream) throws IOException {
- super.write(aStream);
- try {
- friendsLock.readLock().lock();
- UIDObjectFactory.getDefaultFactory().writeStringToUIDMapSet(friends, aStream);
- } finally {
- friendsLock.readLock().unlock();
- }
- }
- }