All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bimserver.shared.WaitingListVirtualObject Maven / Gradle / Ivy

Go to download

Base project for BIMserver plugin development. Some plugins mights also need the Shared library

There is a newer version: 2.0.0
Show newest version
package org.bimserver.shared;

/******************************************************************************
 * Copyright (C) 2009-2016  BIMserver.org
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see {@literal}.
 *****************************************************************************/

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;

import org.bimserver.BimserverDatabaseException;
import org.bimserver.plugins.deserializers.DeserializeException;
import org.bimserver.shared.exceptions.BimServerClientException;
import org.eclipse.emf.ecore.EClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WaitingListVirtualObject {
	private static final Logger LOGGER = LoggerFactory.getLogger(WaitingListVirtualObject.class);
	private final Map> waitingObjects = new HashMap>();
	private final Map openConnections = new HashMap<>();

	public boolean containsKey(T recordNumber) {
		return waitingObjects.containsKey(recordNumber);
	}

	private AtomicInteger getOpenConnectionCounter(long oid) {
		AtomicInteger atomicInteger = openConnections.get(oid);
		if (atomicInteger == null) {
			atomicInteger = new AtomicInteger();
			openConnections.put(oid, atomicInteger);
		}
		return atomicInteger;
	}
	
	public void add(T referenceId, WaitingVirtualObject waitingObject) {
		getOpenConnectionCounter(waitingObject.getObject().getOid()).incrementAndGet();
		
		List waitingList = null;
		if (waitingObjects.containsKey(referenceId)) {
			waitingList = waitingObjects.get(referenceId);
		} else {
			waitingList = new ArrayList();
			waitingObjects.put(referenceId, waitingList);
		}
		waitingList.add(waitingObject);
	}
	
	private void decrementOpenConnections(VirtualObject virtualObject) throws BimserverDatabaseException {
		AtomicInteger openConnectionCounter = getOpenConnectionCounter(virtualObject.getOid());
		int decrementAndGet = openConnectionCounter.decrementAndGet();
		if (decrementAndGet == 0) {
			virtualObject.save();
		} else if (decrementAndGet < 0) {
			throw new BimserverDatabaseException("Inconsistent state");
		}
	}
	
	public void updateNode(T expressId, EClass ec, VirtualObject eObject) throws DeserializeException, BimserverDatabaseException {
		for (WaitingVirtualObject waitingObject : waitingObjects.get(expressId)) {
			if (waitingObject.getStructuralFeature().isMany()) {
				ListWaitingVirtualObject listWaitingObject = (ListWaitingVirtualObject)waitingObject;
				if (((EClass) waitingObject.getStructuralFeature().getEType()).isSuperTypeOf(eObject.eClass())) {
					waitingObject.getObject().setListItemReference(waitingObject.getStructuralFeature(), listWaitingObject.getIndex(), eObject.eClass(), eObject.getOid(), waitingObject.getBufferPosition());
					decrementOpenConnections(waitingObject.getObject());
				} else {
					throw new DeserializeException(waitingObject.getLineNumber(), "Field " + waitingObject.getStructuralFeature().getName() + " of "
							+ waitingObject.getStructuralFeature().getEContainingClass().getName() + " cannot contain a " + eObject.eClass().getName());
				}
			} else {
				if (((EClass) waitingObject.getStructuralFeature().getEType()).isSuperTypeOf(eObject.eClass())) {
					waitingObject.getObject().setReference(waitingObject.getStructuralFeature(), eObject.getOid(), waitingObject.getBufferPosition());
					decrementOpenConnections(waitingObject.getObject());
				} else {
					throw new DeserializeException(waitingObject.getLineNumber(), "Field " + waitingObject.getStructuralFeature().getName() + " of "
							+ waitingObject.getStructuralFeature().getEContainingClass().getName() + " cannot contain a " + eObject.eClass().getName() + "/" + eObject.getOid());
				}
			}
		}
		waitingObjects.remove(expressId);
	}

	public int size() {
		return waitingObjects.size();
	}
	
	public void dumpIfNotEmpty() throws BimServerClientException {
		if (size() > 0) {
			for (Entry> entry : waitingObjects.entrySet()) {
				StringBuilder sb = new StringBuilder("" + entry.getKey() + " ");
				for (WaitingVirtualObject waitingObject : entry.getValue()) {
					sb.append(waitingObject.toString() + " ");
				}
				LOGGER.info(sb.toString());
			}
			throw new BimServerClientException("Waitinglist not empty, this usually means some objects were referred, but not included in the download");
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy