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

org.bimserver.notifications.NewRevisionNotification Maven / Gradle / Ivy

There is a newer version: 1.5.9
Show newest version
package org.bimserver.notifications;

/******************************************************************************
 * 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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.mail.Message;
import javax.mail.internet.InternetAddress;

import org.bimserver.BimServer;
import org.bimserver.BimserverDatabaseException;
import org.bimserver.client.Channel;
import org.bimserver.database.DatabaseSession;
import org.bimserver.database.OldQuery;
import org.bimserver.database.OldQuery.Deep;
import org.bimserver.emf.IfcModelInterface;
import org.bimserver.emf.PackageMetaData;
import org.bimserver.ifc.BasicIfcModel;
import org.bimserver.mail.EmailMessage;
import org.bimserver.mail.MailSystem;
import org.bimserver.models.log.AccessMethod;
import org.bimserver.models.store.ModelCheckerInstance;
import org.bimserver.models.store.ModelCheckerResult;
import org.bimserver.models.store.Project;
import org.bimserver.models.store.Revision;
import org.bimserver.models.store.ServerSettings;
import org.bimserver.models.store.Service;
import org.bimserver.models.store.StorePackage;
import org.bimserver.models.store.Trigger;
import org.bimserver.models.store.User;
import org.bimserver.models.store.UserType;
import org.bimserver.plugins.modelchecker.ModelCheckException;
import org.bimserver.plugins.modelchecker.ModelChecker;
import org.bimserver.plugins.modelchecker.ModelCheckerPlugin;
import org.bimserver.shared.ChannelConnectionException;
import org.bimserver.shared.exceptions.PublicInterfaceNotFoundException;
import org.bimserver.shared.exceptions.ServerException;
import org.bimserver.shared.exceptions.UserException;
import org.bimserver.shared.interfaces.ServiceInterface;
import org.bimserver.shared.interfaces.async.AsyncBimsie1RemoteServiceInterface;
import org.bimserver.shared.interfaces.async.AsyncBimsie1RemoteServiceInterface.NewRevisionCallback;
import org.bimserver.shared.interfaces.bimsie1.Bimsie1RemoteServiceInterface;
import org.bimserver.templating.TemplateIdentifier;
import org.bimserver.webservices.authorization.AdminAuthorization;
import org.bimserver.webservices.authorization.Authorization;
import org.bimserver.webservices.authorization.ExplicitRightsAuthorization;
import org.bimserver.webservices.authorization.UserAuthorization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NewRevisionNotification extends Notification {

	private static final Logger LOGGER = LoggerFactory.getLogger(NewRevisionNotification.class);
	private long roid;
	private long poid;
	private long soid;
	private boolean sendEmail = true;

	public NewRevisionNotification(BimServer bimServer, long poid, long roid, long soid) {
		super(bimServer);
		this.poid = poid;
		this.roid = roid;
		this.soid = soid;
		sendEmail = false;
	}

	public NewRevisionNotification(BimServer bimServer, long poid, long roid) {
		super(bimServer);
		this.poid = poid;
		this.roid = roid;
		this.soid = -1;
	}

	@Override
	public void process() throws BimserverDatabaseException, UserException, ServerException {
		DatabaseSession session = getBimServer().getDatabase().createSession();
		try {
			Project project = session.get(StorePackage.eINSTANCE.getProject(), poid, OldQuery.getDefault());
			if (project == null) {
				LOGGER.error("Project with oid " + poid + " not found");
				return;
			}
			Revision revision = session.get(StorePackage.eINSTANCE.getRevision(), roid, OldQuery.getDefault());
			if (revision == null) {
				LOGGER.error("Revision with roid " + roid + " not found");
				return;
			}
			if  (project.isSendEmailOnNewRevision() && sendEmail) {
				sendEmail(session, project, revision);
			}
			for (Service service : project.getServices()) {
				if (soid == -1 || service.getOid() == soid) {
					triggerNewRevision(session, getBimServer().getNotificationsManager(), getBimServer(), getBimServer().getNotificationsManager().getSiteAddress(), project, roid, Trigger.NEW_REVISION, service);
				}
			}
			if (soid == -1) {
				// Only execute if we are not triggering a specific service with this notification
				NewRevisionTopic newRevisionTopic = getBimServer().getNotificationsManager().getNewRevisionTopic();
				if (newRevisionTopic != null) {
					newRevisionTopic.process(session, poid, roid, this);
				}
				NewRevisionOnSpecificProjectTopic newRevisionOnSpecificProjectTopic = getBimServer().getNotificationsManager().getNewRevisionOnSpecificProjectTopic(new NewRevisionOnSpecificProjectTopicKey(poid));
				if (newRevisionOnSpecificProjectTopic != null) {
					newRevisionOnSpecificProjectTopic.process(session, poid, roid, this);
				}
			}
		} finally {
			session.close();
		}
	}
	
	private void sendEmail(DatabaseSession session, Project project, Revision revision) {
		Set users = getUsers(session, project);
		for (User user : users) {
			String body = null;
			try {
				if (MailSystem.isValidEmailAddress(user.getUsername())) {
					EmailMessage message = getBimServer().getMailSystem().createMessage();
					ServerSettings serverSettings = getBimServer().getServerSettingsCache().getServerSettings();
					
					String emailSenderAddress = serverSettings.getEmailSenderAddress();
					InternetAddress addressFrom = new InternetAddress(emailSenderAddress);
					message.setFrom(addressFrom);
					
					InternetAddress[] addressTo = new InternetAddress[1];
					addressTo[0] = new InternetAddress(user.getUsername());
					message.setRecipients(Message.RecipientType.TO, addressTo);
					
					Map context = new HashMap();
					context.put("name", user.getName());
					context.put("username", user.getUsername());
					context.put("siteaddress", serverSettings.getSiteAddress());
					context.put("revisionId", revision.getId());
					
					Authorization authorization = null;
					if (user.getUserType() == UserType.ADMIN) {
						authorization = new AdminAuthorization(getBimServer().getServerSettingsCache().getServerSettings().getSessionTimeOutSeconds(), TimeUnit.SECONDS);
					} else {
						authorization = new UserAuthorization(getBimServer().getServerSettingsCache().getServerSettings().getSessionTimeOutSeconds(), TimeUnit.SECONDS);
					}
					authorization.setUoid(user.getOid());
					String asHexToken = authorization.asHexToken(getBimServer().getEncryptionKey());
					
					context.put("token", asHexToken);
					context.put("roid", revision.getOid());
					context.put("comment", revision.getComment());
					context.put("projectName", project.getName());
					String subject = null;
					body = getBimServer().getTemplateEngine().process(context, TemplateIdentifier.NEW_REVISION_EMAIL_BODY);
					subject = getBimServer().getTemplateEngine().process(context, TemplateIdentifier.NEW_REVISION_EMAIL_SUBJECT);
					message.setContent(body, "text/html");
					message.setSubject(subject.trim());
					
					LOGGER.info("Sending new revision e-mail to " + user.getUsername());
					
					message.send();
				}
			} catch (Exception e) {
				LOGGER.error(body);
				LOGGER.error("", e);
			}
		}
	}

	private Set getUsers(DatabaseSession session, Project project) {
		Set relatedProjects = getRelatedProjects(project);
		Set users = new HashSet();
		for (Project relatedProject : relatedProjects) {
			for (User user : relatedProject.getHasAuthorizedUsers()) {
				users.add(user);
			}
		}
		return users;
	}
	
	private Set getRelatedProjects(Project project) {
		Set projects = new HashSet();
		Project rootProject = getRootProject(project);
		getAllSubProjects(projects, rootProject);
		return projects;
	}

	private Project getRootProject(Project project) {
		if (project.getParent() != null) {
			return getRootProject(project.getParent());
		}
		return project;
	}
	
	private void getAllSubProjects(Set projects, Project project) {
		projects.add(project);
		for (Project subProject : project.getSubProjects()) {
			getAllSubProjects(projects, subProject);
		}
	}

	public void triggerNewRevision(DatabaseSession session, NotificationsManager notificationsManager, final BimServer bimServer, String siteAddress, Project project, final long roid, Trigger trigger, final Service service) throws UserException, ServerException {
		if (service.getTrigger() == trigger) {
			Channel channel = null;
			try {
				IfcModelInterface model = null;
				for (ModelCheckerInstance modelCheckerInstance : service.getModelCheckers()) {
					if (modelCheckerInstance.isValid()) {
						ModelCheckerPlugin modelCheckerPlugin = bimServer.getPluginManager().getModelCheckerPlugin(modelCheckerInstance.getModelCheckerPluginClassName(), true);
						if (modelCheckerPlugin != null) {
							ModelChecker modelChecker = modelCheckerPlugin.createModelChecker(null);
							ModelCheckerResult result;
							try {
								if (model == null) {
									PackageMetaData packageMetaData = bimServer.getMetaDataManager().getPackageMetaData(project.getSchema());
									model = new BasicIfcModel(packageMetaData, null);
									Revision revision;
									try {
										revision = session.get(roid, OldQuery.getDefault());
										session.getMap(model, new OldQuery(packageMetaData, project.getId(), revision.getId(), revision.getOid(), null, Deep.NO));
									} catch (BimserverDatabaseException e) {
										LOGGER.error("", e);
									}
								}
								result = modelChecker.check(model, modelCheckerInstance.getCompiled());
								if (!result.isValid()) {
									LOGGER.info("Not triggering");
									return;
								}
							} catch (ModelCheckException e) {
								LOGGER.info("Not triggering");
								return;
							}
						}
					}
				}
				channel = notificationsManager.getChannel(service);
				final Bimsie1RemoteServiceInterface remoteServiceInterface = channel.get(Bimsie1RemoteServiceInterface.class);
				long writeProjectPoid = service.getWriteRevision() == null ? -1 : service.getWriteRevision().getOid();
				long writeExtendedDataRoid = service.getWriteExtendedData() != null ? roid : -1;
				@SuppressWarnings("unused")
				long readRevisionRoid = service.isReadRevision() ? roid : -1;
				long readExtendedDataRoid = service.getReadExtendedData() != null ? roid : -1;
				
				List roidsList = new ArrayList<>();
				Set relatedProjects = getRelatedProjects(project);
				for (Project p : relatedProjects) {
					if (p.getLastRevision() != null) {
						roidsList.add(p.getLastRevision().getOid());
					}
				}
				
				long[] roids = new long[roidsList.size()];
				for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy