From 8b0170a0e2d6c7ed7407403b523c295c3d5685ca Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 8 Nov 2012 16:39:18 +0100
Subject: [PATCH] OO-407: more admin informations, popup to create a room,
 implements more exception to be user friendly if the server is not available

---
 .../OpenMeetingsEditController.java           |  24 +-
 .../OpenMeetingsEditFormController.java       | 107 ++++++
 .../nodes/openmeetings/_content/edit.html     |   7 +-
 .../_i18n/LocalStrings_de.properties          |   9 +-
 .../org/olat/modules/ModuleConfiguration.java |   7 +-
 ...eption.java => OpenMeetingsException.java} |  37 +-
 .../manager/OpenMeetingsManager.java          |  33 +-
 .../manager/OpenMeetingsManagerImpl.java      | 337 ++++++++++++++++--
 .../openmeetings/model/OpenMeetingsRoom.java  |  41 +++
 .../openmeetings/model/OpenMeetingsUser.java  |  76 ++++
 .../openmeetings/model/RoomReturnInfo.java    |  60 ++++
 .../ui/OpenMeetingsAdminController.java       |  19 +-
 .../OpenMeetingsAdminRoomInfosController.java | 108 ++++++
 ...penMeetingsAdminRoomMembersController.java | 224 ++++++++++++
 ...enMeetingsAdminRoomRawInfosController.java |  63 ++++
 .../ui/OpenMeetingsAdminRoomsController.java  | 211 +++++++++++
 .../OpenMeetingsConfigurationController.java  |  14 +-
 .../ui/OpenMeetingsRoomEditController.java    |   7 +-
 .../ui/OpenMeetingsRoomsDataModel.java        | 125 +++++++
 .../ui/OpenMeetingsRunController.java         |  56 ++-
 .../openmeetings/ui/_content/room.html        |   7 +
 .../openmeetings/ui/_content/room_admin.html  |   7 +
 .../ui/_content/room_user_admin.html          |   1 +
 .../ui/_i18n/LocalStrings_de.properties       |  34 +-
 24 files changed, 1524 insertions(+), 90 deletions(-)
 create mode 100644 src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java
 rename src/main/java/org/olat/modules/openmeetings/manager/{OpenMeetingsNotAvailableException.java => OpenMeetingsException.java} (60%)
 create mode 100644 src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsUser.java
 create mode 100644 src/main/java/org/olat/modules/openmeetings/model/RoomReturnInfo.java
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomInfosController.java
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomMembersController.java
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomRawInfosController.java
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomsController.java
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomsDataModel.java
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/_content/room.html
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/_content/room_admin.html
 create mode 100644 src/main/java/org/olat/modules/openmeetings/ui/_content/room_user_admin.html

diff --git a/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditController.java b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditController.java
index 6d61ed36d5c..a32f1a16898 100644
--- a/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditController.java
+++ b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditController.java
@@ -37,7 +37,7 @@ import org.olat.course.condition.ConditionEditController;
 import org.olat.course.editor.NodeEditController;
 import org.olat.course.nodes.OpenMeetingsCourseNode;
 import org.olat.course.run.userview.UserCourseEnvironment;
-import org.olat.modules.openmeetings.ui.OpenMeetingsRoomEditController;
+import org.olat.modules.openmeetings.manager.OpenMeetingsException;
 
 /**
  * 
@@ -54,9 +54,9 @@ public class OpenMeetingsEditController extends ActivateableTabbableDefaultContr
 	private VelocityContainer editVc;
 	private ConditionEditController accessibilityCondContr;
 	private TabbedPane tabPane;
-	private OpenMeetingsRoomEditController editForm;
 
 	private final OpenMeetingsCourseNode courseNode;
+	
 
 	public OpenMeetingsEditController(UserRequest ureq, WindowControl wControl, OpenMeetingsCourseNode courseNode,
 			ICourse course, UserCourseEnvironment userCourseEnv) {
@@ -69,13 +69,15 @@ public class OpenMeetingsEditController extends ActivateableTabbableDefaultContr
 				accessCondition, "accessabilityConditionForm", AssessmentHelper.getAssessableNodes(course.getEditorTreeModel(), courseNode),
 				userCourseEnv);
 		listenTo(accessibilityCondContr);
-
-		OLATResourceable ores = OresHelper.createOLATResourceableInstance(course.getResourceableTypeName(), course.getResourceableId());
-		editForm = new OpenMeetingsRoomEditController(ureq, wControl, null, ores, courseNode.getIdent(), course.getCourseTitle(), true);
-		listenTo(editForm);
 		
 		editVc = createVelocityContainer("edit");
-		editVc.put("editRooms", editForm.getInitialComponent());
+		try {
+			OLATResourceable ores = OresHelper.createOLATResourceableInstance(course.getResourceableTypeName(), course.getResourceableId());
+			Controller editForm = new OpenMeetingsEditFormController(ureq, getWindowControl(), ores, courseNode, course.getCourseTitle());
+			editVc.put("editRooms", editForm.getInitialComponent());
+		} catch (OpenMeetingsException e) {
+			editVc.contextPut("error", e.getType().i18nKey());
+		}
 	}
 
 	@Override
@@ -90,10 +92,7 @@ public class OpenMeetingsEditController extends ActivateableTabbableDefaultContr
 
 	@Override
 	protected void doDispose() {
-		if(editForm != null) {
-			removeAsListenerAndDispose(editForm);
-			editForm = null;
-		}
+		//
 	}
 
 	@Override
@@ -109,8 +108,6 @@ public class OpenMeetingsEditController extends ActivateableTabbableDefaultContr
 				courseNode.setPreConditionAccess(cond);
 				fireEvent(ureq, NodeEditController.NODECONFIG_CHANGED_EVENT);
 			}
-		} else if (source == editForm) {
-			//nothing to do
 		}
 	}
 
@@ -120,4 +117,5 @@ public class OpenMeetingsEditController extends ActivateableTabbableDefaultContr
 				accessibilityCondContr.getWrappedDefaultAccessConditionVC(translate("condition.accessibility.title")));
 		tabbedPane.addTab(translate(PANE_TAB_VCCONFIG), editVc);
 	}
+
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java
new file mode 100644
index 00000000000..6e69c18bb3b
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java
@@ -0,0 +1,107 @@
+package org.olat.course.nodes.openmeetings;
+
+import org.olat.core.CoreSpringFactory;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
+import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
+import org.olat.core.id.OLATResourceable;
+import org.olat.course.nodes.OpenMeetingsCourseNode;
+import org.olat.modules.openmeetings.manager.OpenMeetingsManager;
+import org.olat.modules.openmeetings.manager.OpenMeetingsException;
+import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+import org.olat.modules.openmeetings.ui.OpenMeetingsRoomEditController;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public class OpenMeetingsEditFormController extends FormBasicController {
+	
+	private FormLink editLink;
+	private CloseableModalController cmc;
+	private OpenMeetingsRoomEditController editController;
+	
+	private String courseTitle;
+	private final OLATResourceable course;
+	private final OpenMeetingsCourseNode courseNode;
+	private final OpenMeetingsManager openMeetingsManager;
+	
+	private OpenMeetingsRoom room;
+
+	public OpenMeetingsEditFormController(UserRequest ureq, WindowControl wControl, OLATResourceable course,
+			OpenMeetingsCourseNode courseNode, String courseTitle)
+	    throws OpenMeetingsException{
+		super(ureq, wControl);
+		
+		this.course = course;
+		this.courseNode = courseNode;
+		this.courseTitle = courseTitle;
+		openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class);
+
+		room = openMeetingsManager.getRoom(null, course, courseNode.getIdent());
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		if(room == null) {
+			FormLayoutContainer buttonContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
+			formLayout.add(buttonContainer);
+			editLink = uifactory.addFormLink("create.room", buttonContainer, Link.BUTTON);
+		} else {
+			String name = room.getName();
+			uifactory.addStaticTextElement("room.name", "room.name", name, formLayout);
+
+			FormLayoutContainer buttonContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
+			formLayout.add(buttonContainer);
+			editLink = uifactory.addFormLink("edit.room", buttonContainer, Link.BUTTON);	
+		}
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if(source == editLink) {
+			doEditRoom(ureq);
+		} else {
+			super.formInnerEvent(ureq, source, event);
+		}
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+
+	protected void doEditRoom(UserRequest ureq) {
+		removeAsListenerAndDispose(editController);
+		removeAsListenerAndDispose(cmc);
+		
+		try {
+			editController = new OpenMeetingsRoomEditController(ureq, getWindowControl(), null, course, courseNode.getIdent(), courseTitle, true);
+			listenTo(editController);
+
+			cmc = new CloseableModalController(getWindowControl(), translate("close"), editController.getInitialComponent(), true, translate("edit.room"));
+			listenTo(cmc);
+			cmc.activate();
+		} catch (Exception e) {
+			showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
+		}
+	}
+	
+	
+
+}
diff --git a/src/main/java/org/olat/course/nodes/openmeetings/_content/edit.html b/src/main/java/org/olat/course/nodes/openmeetings/_content/edit.html
index b6db8fce606..a2baa0d03a9 100644
--- a/src/main/java/org/olat/course/nodes/openmeetings/_content/edit.html
+++ b/src/main/java/org/olat/course/nodes/openmeetings/_content/edit.html
@@ -1,2 +1,5 @@
-
-$r.render('editRooms')
+#if($error)
+	<div class="b_warning">$r.translate($error)</div>
+#elseif($r.available("editRooms"))
+	$r.render("editRooms")
+#end
diff --git a/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties
index 8245cfdee3f..319f3264823 100644
--- a/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties
@@ -1,8 +1,13 @@
 error.vmsNotAvailable=$org.olat.modules.openmeetings.ui\:error.notAvailable
 table.empty=$org.olat.modules.openmeetings.ui\:table.empty
 pane.tab.accessibility=Zugang
-pane.tab.vcconfig=Konfiguration
+pane.tab.vcconfig=Raum
 condition.accessibility.title=Zugang
 title_vc=OpenMeetings
 guestnoaccess.title=$org.olat.course.nodes\:guestnoaccess.title
-guestnoaccess.message=$org.olat.course.nodes\:guestnoaccess.message
\ No newline at end of file
+guestnoaccess.message=$org.olat.course.nodes\:guestnoaccess.message
+create.room=Raum erstellen
+edit.room=Raum editieren
+
+error.notAvailable=$org.olat.modules.openmeetings.ui\:error.notAvailable
+error.unkown=$org.olat.modules.openmeetings.ui\:error.unkown
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/ModuleConfiguration.java b/src/main/java/org/olat/modules/ModuleConfiguration.java
index 29d104f976d..08b8b211b8b 100644
--- a/src/main/java/org/olat/modules/ModuleConfiguration.java
+++ b/src/main/java/org/olat/modules/ModuleConfiguration.java
@@ -35,19 +35,22 @@ import java.util.Map;
  * @author gnaegi
  */
 public class ModuleConfiguration implements Serializable {
+
+	private static final long serialVersionUID = 5997068149344924126L;
+
 	/**
 	 * Configuration flag for the configuration version. The configuration version
 	 * is stored using an Integer in the module configuration. 
 	 */
 	private static final String CONFIG_VERSION = "configversion";
 
-	private Map config;
+	private Map<String,Object> config;
 	
 	/**
 	 * Default constructor.
 	 */
 	public ModuleConfiguration() {
-		config = new HashMap();
+		config = new HashMap<String,Object>();
 	}
 
 	/**
diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsNotAvailableException.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsException.java
similarity index 60%
rename from src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsNotAvailableException.java
rename to src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsException.java
index 703c7482112..34e54ec62c7 100644
--- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsNotAvailableException.java
+++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsException.java
@@ -28,26 +28,49 @@ package org.olat.modules.openmeetings.manager;
  *
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
-public class OpenMeetingsNotAvailableException extends Exception {
+public class OpenMeetingsException extends Exception {
 	
 	private static final long serialVersionUID = 3260533359384969602L;
 	
-	public static final String I18N_KEY = "error.notAvailable";
+	public static final String SERVER_NOT_I18N_KEY = "error.notAvailable";
 
-	public OpenMeetingsNotAvailableException() {
-		//
+	private final Type type;
+	
+	public OpenMeetingsException(Type type) {
+		this.type = type;
 	}
 	
-	public OpenMeetingsNotAvailableException(String message) {
+	public OpenMeetingsException(String message, Type type) {
 		super(message);
+		this.type = type;
 	}
 	
-	public OpenMeetingsNotAvailableException(String message, Exception cause) {
+	public OpenMeetingsException(String message, Exception cause, Type type) {
 		super(message, cause);
+		this.type = type;
 	}
 	
-	public OpenMeetingsNotAvailableException(Exception cause) {
+	public OpenMeetingsException(Exception cause, Type type) {
 		super(cause);
+		this.type = type;
+	}
+	
+	public Type getType() {
+		return type;
 	}
 
+	public enum Type {
+		unkown("error.unkown"),
+		serverNotAvailable("error.notAvailable");
+
+		private final String i18nKey;
+		
+		private Type(String i18nKey) {
+			this.i18nKey = i18nKey;
+		}
+		
+		public String i18nKey() {
+			return i18nKey;
+		}
+	}
 }
diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java
index 19237fdf6a1..8d1d80c343b 100644
--- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java
+++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java
@@ -19,12 +19,14 @@
  */
 package org.olat.modules.openmeetings.manager;
 
+import java.util.List;
 import java.util.Locale;
 
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+import org.olat.modules.openmeetings.model.OpenMeetingsUser;
 
 /**
  * 
@@ -34,21 +36,46 @@ import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
  */
 public interface OpenMeetingsManager {
 	
+	public String getOpenOLATExternalType();
+	
 	
 	public String getURL(Identity identity, long roomId, String securedHash, Locale language);
 	
-	public String setUser(Identity identity, long roomId);
+	public String setUserToRoom(Identity identity, long roomId, boolean moderator)
+	throws OpenMeetingsException;
 	
 	public Long getRoomId(BusinessGroup group, OLATResourceable ores, String subIdentifier);
+	
+	public List<OpenMeetingsRoom> getOpenOLATRooms();
 
-	public OpenMeetingsRoom getRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier);
+	public OpenMeetingsRoom getRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier)
+	throws OpenMeetingsException;
 	
 	public OpenMeetingsRoom addRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier, OpenMeetingsRoom room);
 	
 	public OpenMeetingsRoom updateRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier, OpenMeetingsRoom room);
 	
+	public boolean deleteRoom(OpenMeetingsRoom room);
+	
+	
+	public List<OpenMeetingsUser> getUsersOf(OpenMeetingsRoom room);
+	
+	/**
+	 * Kick all users from a room
+	 * @param room
+	 * @return
+	 */
+	public boolean removeUsersFromRoom(OpenMeetingsRoom room);
+	
+	/**
+	 * Kick user of its meetings
+	 * @param publicSID
+	 * @return
+	 */
+	public boolean removeUser(String publicSID);
+	
 	
-	public boolean checkConnection(String url, String login, String password) throws OpenMeetingsNotAvailableException;
+	public boolean checkConnection(String url, String login, String password) throws OpenMeetingsException;
 	
 	public void deleteAll(BusinessGroup group, OLATResourceable ores, String subIdentifier);
 
diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java
index 22152ffff9b..4b3ab82abf0 100644
--- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java
+++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java
@@ -20,7 +20,13 @@
 package org.olat.modules.openmeetings.manager;
 
 import java.io.StringWriter;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 
 import javax.annotation.PostConstruct;
 
@@ -34,28 +40,44 @@ import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.WebappHelper;
+import org.olat.core.util.resource.OresHelper;
 import org.olat.core.util.xml.XStreamHelper;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.openmeetings.OpenMeetingsModule;
 import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+import org.olat.modules.openmeetings.model.OpenMeetingsUser;
+import org.olat.modules.openmeetings.model.RoomReturnInfo;
 import org.olat.properties.Property;
 import org.olat.properties.PropertyManager;
 import org.olat.user.UserDataDeletable;
+import org.openmeetings.app.conference.session.xsd.RoomClient;
 import org.openmeetings.app.persistence.beans.rooms.xsd.Rooms;
 import org.openmeetings.axis.services.AddRoomWithModerationAndExternalType;
 import org.openmeetings.axis.services.AddRoomWithModerationAndExternalTypeResponse;
+import org.openmeetings.axis.services.DeleteRoom;
+import org.openmeetings.axis.services.DeleteRoomResponse;
 import org.openmeetings.axis.services.GetRoomById;
 import org.openmeetings.axis.services.GetRoomByIdResponse;
+import org.openmeetings.axis.services.GetRoomWithClientObjectsById;
+import org.openmeetings.axis.services.GetRoomWithClientObjectsByIdResponse;
 import org.openmeetings.axis.services.GetRoomsPublic;
 import org.openmeetings.axis.services.GetRoomsPublicResponse;
+import org.openmeetings.axis.services.GetRoomsWithCurrentUsersByListAndType;
+import org.openmeetings.axis.services.GetRoomsWithCurrentUsersByListAndTypeResponse;
 import org.openmeetings.axis.services.GetSession;
 import org.openmeetings.axis.services.GetSessionResponse;
+import org.openmeetings.axis.services.KickUser;
+import org.openmeetings.axis.services.KickUserByPublicSID;
+import org.openmeetings.axis.services.KickUserByPublicSIDResponse;
+import org.openmeetings.axis.services.KickUserResponse;
 import org.openmeetings.axis.services.LoginUser;
 import org.openmeetings.axis.services.LoginUserResponse;
 import org.openmeetings.axis.services.SetUserObjectAndGenerateRoomHashByURL;
 import org.openmeetings.axis.services.SetUserObjectAndGenerateRoomHashByURLResponse;
 import org.openmeetings.axis.services.UpdateRoomWithModeration;
 import org.openmeetings.axis.services.UpdateRoomWithModerationResponse;
+import org.openmeetings.axis.services.xsd.RoomReturn;
+import org.openmeetings.axis.services.xsd.RoomUser;
 import org.openmeetings.stubs.RoomServiceStub;
 import org.openmeetings.stubs.UserServiceStub;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -90,6 +112,8 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 	public void init() {
 		xStream = XStreamHelper.createXStreamInstance();
 		xStream.alias("room", OpenMeetingsRoom.class);
+		xStream.omitField(OpenMeetingsRoom.class, "property");
+		xStream.omitField(OpenMeetingsRoom.class, "numOfUsers");
 		
 		userDeletionManager.registerDeletableUserData(this);
 		
@@ -106,6 +130,92 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 		return prop.getLongValue();
 	}
 	
+	@Override
+	public List<OpenMeetingsRoom> getOpenOLATRooms() {
+		try {
+			String adminSID = adminLogin();
+			RoomServiceStub roomWs = getRoomWebService();
+
+			GetRoomsWithCurrentUsersByListAndType getRooms = new GetRoomsWithCurrentUsersByListAndType();
+			getRooms.setAsc(true);
+			getRooms.setExternalRoomType(getOpenOLATExternalType());
+			getRooms.setOrderby("name");
+			getRooms.setStart(0);
+			getRooms.setMax(2000);
+			getRooms.setSID(adminSID);
+			
+			Map<Long,RoomReturnInfo> realRooms = new HashMap<Long,RoomReturnInfo>();
+			
+			//get rooms on openmeetings
+			GetRoomsWithCurrentUsersByListAndTypeResponse getRoomsResponse = roomWs.getRoomsWithCurrentUsersByListAndType(getRooms);
+			RoomReturn[] roomsRet = getRoomsResponse.get_return();
+			if(roomsRet != null) {
+				for(RoomReturn roomRet:roomsRet) {
+					RoomReturnInfo info = new RoomReturnInfo();
+					info.setName(roomRet.getName());
+					info.setRoomId(roomRet.getRoom_id());
+					int numOfUsers = 0;
+					if(roomRet.getRoomUser() != null) {
+						for(RoomUser user:roomRet.getRoomUser()) {
+							if(user != null) {
+								numOfUsers++;
+							}
+						}
+					}
+					info.setNumOfUsers(numOfUsers);
+					realRooms.put(new Long(roomRet.getRoom_id()), info);
+				}
+			}
+
+			//get properties saved
+			List<Property> props = getProperties();
+			Map<Long,String> roomIdToResources = getResourceNames(props);
+
+			
+			List<OpenMeetingsRoom> rooms = new ArrayList<OpenMeetingsRoom>();
+			for(Property prop:props) {
+				
+				Long roomId = new Long(prop.getLongValue());
+				RoomReturnInfo infos = realRooms.get(roomId);
+				if(infos != null) {
+					OpenMeetingsRoom room = deserializeRoom(prop.getTextValue());
+					room.setProperty(prop);
+					room.setName(infos.getName());
+					room.setNumOfUsers(infos.getNumOfUsers());
+					String resourceName = roomIdToResources.get(roomId);
+					if(resourceName != null) {
+						room.setResourceName(resourceName);
+					}
+					rooms.add(room);
+				}
+			}
+			return rooms;
+		} catch (Exception e) {
+			log.error("", e);
+			return null;
+		}
+	}
+	
+	private Map<Long,String> getResourceNames(List<Property> properties) {
+		Map<Long,String> roomIdToResourceName = new HashMap<Long,String>();
+		
+		List<ResourceRoom> resources = new ArrayList<ResourceRoom>();
+		for(Property prop:properties) {
+			Long roomId = prop.getLongValue();
+			if(prop.getGrp() != null) {
+				roomIdToResourceName.put(roomId, prop.getGrp().getName());
+			} else {
+				
+				ResourceRoom rroom = new ResourceRoom();
+				rroom.setRoomId(roomId);
+				OLATResourceable ores = OresHelper.createOLATResourceableInstance(prop.getResourceTypeName(), prop.getResourceTypeId());
+				rroom.setResource(ores);
+			}
+		}
+		return roomIdToResourceName;
+		
+	}
+
 	@Override
 	public String getURL(Identity identity, long roomId, String securedHash, Locale locale) {
 		StringBuilder sb = new StringBuilder();
@@ -121,15 +231,15 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 		return sb.toString();
 	}
 	
-	
 	@Override
-	public String setUser(Identity identity, long roomId) {
+	public String setUserToRoom(Identity identity, long roomId, boolean moderator)
+	throws OpenMeetingsException {
 		try {
 			UserServiceStub userWs = getUserWebService();
 			String adminSessionId = adminLogin();
 
 			SetUserObjectAndGenerateRoomHashByURL userObj = new SetUserObjectAndGenerateRoomHashByURL();
-			userObj.setBecomeModeratorAsInt(0);
+			userObj.setBecomeModeratorAsInt(moderator ? 1 : 0);
 			userObj.setEmail(identity.getUser().getProperty(UserConstants.EMAIL, null));
 			userObj.setExternalUserId(getOpenOLATUserExternalId(identity));
 			userObj.setExternalUserType(getOpenOLATExternalType());
@@ -146,12 +256,13 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 			return hashedUrl;
 		} catch (Exception e) {
 			log.error("", e);
-			return null;
+			throw translateException(e, 0);
 		}
 	}
 
 	@Override
-	public OpenMeetingsRoom getRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier) {
+	public OpenMeetingsRoom getRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier) 
+	throws OpenMeetingsException{
 		Property prop = getProperty(group, ores, subIdentifier);
 		if(prop == null) {
 			return null;
@@ -164,33 +275,51 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 				OpenMeetingsRoom room = deserializeRoom(prop.getTextValue());
 				getRoomById(sessionId, room, roomId.longValue());
 				return room;
-			} catch (Exception e) {
-				log.error("", e);
+			} catch(OpenMeetingsException e) {
+				throw e;
 			}
 		}
-		
 		return null;
 	}
 	
-	private OpenMeetingsRoom getRoomById(String sid, OpenMeetingsRoom room, long roomId) throws Exception {
-		RoomServiceStub roomWs = getRoomWebService();
-		GetRoomById getRoomById = new GetRoomById();
-		getRoomById.setSID(sid);
-		getRoomById.setRooms_id(roomId);
-		GetRoomByIdResponse getRoomResponse = roomWs.getRoomById(getRoomById);
-		Rooms omRoom = getRoomResponse.get_return();
-		if(omRoom != null) {
-			room.setComment(omRoom.getComment());
-			room.setModerated(omRoom.getIsModeratedRoom());
-			room.setName(omRoom.getName());
-			room.setRoomId(omRoom.getRooms_id());
-			room.setSize(omRoom.getNumberOfPartizipants());
-			room.setType(omRoom.getRoomtype().getRoomtypes_id());
-			return room;
-		} else {
-			return null;
+	private OpenMeetingsRoom getRoomById(String sid, OpenMeetingsRoom room, long roomId)
+	throws OpenMeetingsException {
+		try {
+			RoomServiceStub roomWs = getRoomWebService();
+			GetRoomById getRoomById = new GetRoomById();
+			getRoomById.setSID(sid);
+			getRoomById.setRooms_id(roomId);
+			GetRoomByIdResponse getRoomResponse = roomWs.getRoomById(getRoomById);
+			Rooms omRoom = getRoomResponse.get_return();
+			if(omRoom != null) {
+				room.setComment(omRoom.getComment());
+				room.setModerated(omRoom.getIsModeratedRoom());
+				room.setName(omRoom.getName());
+				room.setRoomId(omRoom.getRooms_id());
+				room.setSize(omRoom.getNumberOfPartizipants());
+				room.setType(omRoom.getRoomtype().getRoomtypes_id());
+				return room;
+			} else {
+				return null;
+			}
+		} catch (Exception e) {
+			throw translateException(e, 0);
 		}
 	}
+	
+	private OpenMeetingsException translateException(Exception e, long ret) {
+		OpenMeetingsException.Type type = OpenMeetingsException.Type.unkown;
+		if(e instanceof AxisFault) {
+			Throwable cause = e.getCause();
+			if(cause instanceof ConnectException
+					&& cause.getMessage() != null
+					&& cause.getMessage().contains("onnection refused")) {
+				type = OpenMeetingsException.Type.serverNotAvailable;
+			}
+		}
+		return new OpenMeetingsException(e, type);
+	}
+	
 
 	@Override
 	public OpenMeetingsRoom addRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier, OpenMeetingsRoom room) {
@@ -235,7 +364,8 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 		return identity.getName() + "@" + WebappHelper.getInstanceId();
 	}
 	
-	private String getOpenOLATExternalType() {
+	@Override
+	public String getOpenOLATExternalType() {
 		return "openolat_" + WebappHelper.getInstanceId();
 	}
 
@@ -271,6 +401,130 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 		}
 	}
 	
+	@Override
+	public boolean deleteRoom(OpenMeetingsRoom room) {
+		try {
+			String adminSID = adminLogin();
+			RoomServiceStub roomWs = getRoomWebService();
+			DeleteRoom getRoomCl = new DeleteRoom();
+			getRoomCl.setRooms_id(room.getRoomId());
+			getRoomCl.setSID(adminSID);
+			DeleteRoomResponse deleteRoomResponse = roomWs.deleteRoom(getRoomCl);
+
+			long ret = deleteRoomResponse.get_return();
+			boolean ok = ret > 0;
+			if(ok && room.getProperty() != null) {
+				propertyManager.deleteProperty(room.getProperty());
+			}
+			return ok;
+		} catch (Exception e) {
+			log.error("", e);
+			return false;
+		}
+	}
+
+	@Override
+	public List<OpenMeetingsUser> getUsersOf(OpenMeetingsRoom room) {
+		try {
+			String adminSID = adminLogin();
+			RoomServiceStub roomWs = getRoomWebService();
+			GetRoomWithClientObjectsById getRoomCl = new GetRoomWithClientObjectsById();
+			getRoomCl.setRooms_id(room.getRoomId());
+			getRoomCl.setSID(adminSID);
+			GetRoomWithClientObjectsByIdResponse getRoomClResponse = roomWs.getRoomWithClientObjectsById(getRoomCl);
+
+			RoomReturn roomClRet = getRoomClResponse.get_return();
+			if(roomClRet != null) {
+				RoomUser[] userArr = roomClRet.getRoomUser();
+				return convert(userArr);
+			}
+			return Collections.emptyList();
+		} catch (Exception e) {
+			log.error("", e);
+			return Collections.emptyList();
+		}
+	}
+	
+	private List<OpenMeetingsUser> convert(RoomUser[] clients) {
+		List<OpenMeetingsUser> users = new ArrayList<OpenMeetingsUser>();
+		if(clients != null) {
+			for(RoomUser client:clients) {
+				OpenMeetingsUser user = convert(client);
+				if(user != null) {
+					users.add(user);
+				}
+			}
+		}
+		return users;
+	}
+	
+	private OpenMeetingsUser convert(RoomUser client) {
+		if(client == null) {
+			return null;
+		}
+		OpenMeetingsUser user = new OpenMeetingsUser();
+		user.setPublicSID(client.getPublicSID());
+		user.setFirstName(client.getFirstname());
+		user.setLastName(client.getLastname());
+		return user;
+	}
+	
+	private List<OpenMeetingsUser> convert(RoomClient[] clients) {
+		List<OpenMeetingsUser> users = new ArrayList<OpenMeetingsUser>();
+		for(RoomClient client:clients) {
+			OpenMeetingsUser user = convert(client);
+			if(user != null) {
+				users.add(user);
+			}
+		}
+		return users;
+	}
+	
+	private OpenMeetingsUser convert(RoomClient client) {
+		if(client == null) {
+			return null;
+		}
+		OpenMeetingsUser user = new OpenMeetingsUser();
+		user.setPublicSID(client.getPublicSID());
+		user.setFirstName(client.getFirstname());
+		user.setLastName(client.getLastname());
+		user.setExternalUserID(client.getExternalUserId());
+		user.setExternalUserType(client.getExternalUserType());
+		return user;
+	}
+
+	@Override
+	public boolean removeUser(String publicSID) {
+		try {
+			String adminSID = adminLogin();
+			UserServiceStub userWs = getUserWebService();
+			KickUserByPublicSID kickUser = new KickUserByPublicSID();
+			kickUser.setSID(adminSID);
+			kickUser.setPublicSID(publicSID);
+			KickUserByPublicSIDResponse kickResponse = userWs.kickUserByPublicSID(kickUser);
+			return kickResponse.get_return();
+		} catch (Exception e) {
+			log.error("", e);
+			return false;
+		}
+	}
+
+	@Override
+	public boolean removeUsersFromRoom(OpenMeetingsRoom room) {	
+		try {
+			String adminSID = adminLogin();
+			RoomServiceStub roomWs = getRoomWebService();
+			KickUser kickUser = new KickUser();
+			kickUser.setRoom_id(room.getRoomId());
+			kickUser.setSID_Admin(adminSID);
+			KickUserResponse kickResponse = roomWs.kickUser(kickUser);
+			return kickResponse.get_return();
+		} catch (Exception e) {
+			log.error("", e);
+			return false;
+		}
+	}
+
 	private String getSessionID() {
 		try {
 			GetSession  getSession = new GetSession();
@@ -330,7 +584,7 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 
 	@Override
 	public boolean checkConnection(String url, String login, String password)
-	throws OpenMeetingsNotAvailableException {
+	throws OpenMeetingsException {
 		try {
 			String endPoint = cleanUrl(url) + "/services/UserService?wsdl";
 			UserServiceStub userWs = new UserServiceStub(endPoint);
@@ -340,9 +594,8 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 			String sessionId = getSessionResponse.get_return().getSession_id();
 			return StringHelper.containsNonWhitespace(sessionId);
 		} catch (Exception e) {
-			e.printStackTrace();
+			throw translateException(e, 0);
 		}
-		return false;
 	}
 	
 	@Override
@@ -351,6 +604,10 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 	}
 
 	//Properties
+	private final List<Property> getProperties() {
+		return propertyManager.listProperties(null, null, null, OM_CATEGORY, null);
+	}
+	
 	private final Property getProperty(BusinessGroup group, OLATResourceable courseResource, String subIdentifier) {
 		return propertyManager.findProperty(null, group, courseResource, OM_CATEGORY, subIdentifier);
 	}
@@ -406,4 +663,26 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel
 	private String cleanUrl(String url) {
 		return url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
 	}
+	
+	private static class ResourceRoom {
+		
+		private Long roomId;
+		private OLATResourceable resource;
+		
+		public Long getRoomId() {
+			return roomId;
+		}
+		
+		public void setRoomId(Long roomId) {
+			this.roomId = roomId;
+		}
+		
+		public OLATResourceable getResource() {
+			return resource;
+		}
+		
+		public void setResource(OLATResourceable resource) {
+			this.resource = resource;
+		}
+	}
 }
diff --git a/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsRoom.java b/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsRoom.java
index 520a8f2bc91..f336fb12247 100644
--- a/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsRoom.java
+++ b/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsRoom.java
@@ -19,6 +19,8 @@
  */
 package org.olat.modules.openmeetings.model;
 
+import org.olat.properties.Property;
+
 
 /**
  * 
@@ -35,6 +37,18 @@ public class OpenMeetingsRoom {
 	private boolean moderated;
 	private boolean recordingAllowed;
 	
+	private transient Property property;
+	private transient int numOfUsers;
+	private transient String resourceName;
+	
+	public OpenMeetingsRoom() {
+		//
+	}
+	
+	public OpenMeetingsRoom(Property property) {
+		this.property = property;
+	}
+	
 	public long getRoomId() {
 		return roomId;
 	}
@@ -90,4 +104,31 @@ public class OpenMeetingsRoom {
 	public void setRecordingAllowed(boolean recordingAllowed) {
 		this.recordingAllowed = recordingAllowed;
 	}
+
+	public Property getProperty() {
+		return property;
+	}
+
+	public void setProperty(Property property) {
+		this.property = property;
+	}
+
+	public int getNumOfUsers() {
+		return numOfUsers;
+	}
+
+	public void setNumOfUsers(int numOfUsers) {
+		this.numOfUsers = numOfUsers;
+	}
+
+	public String getResourceName() {
+		return resourceName;
+	}
+
+	public void setResourceName(String resourceName) {
+		this.resourceName = resourceName;
+	}
+	
+	
+	
 }
diff --git a/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsUser.java b/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsUser.java
new file mode 100644
index 00000000000..1a2af56d80f
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsUser.java
@@ -0,0 +1,76 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * 12.10.2011 by frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.openmeetings.model;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class OpenMeetingsUser {
+	
+	private String publicSID;
+	private String firstName;
+	private String lastName;
+	private String externalUserType;
+	private String externalUserID;
+
+	public String getPublicSID() {
+		return publicSID;
+	}
+
+	public void setPublicSID(String publicSID) {
+		this.publicSID = publicSID;
+	}
+
+	public String getFirstName() {
+		return firstName;
+	}
+
+	public void setFirstName(String firstName) {
+		this.firstName = firstName;
+	}
+
+	public String getLastName() {
+		return lastName;
+	}
+
+	public void setLastName(String lastName) {
+		this.lastName = lastName;
+	}
+
+	public String getExternalUserID() {
+		return externalUserID;
+	}
+
+	public void setExternalUserID(String externalUserID) {
+		this.externalUserID = externalUserID;
+	}
+
+	public String getExternalUserType() {
+		return externalUserType;
+	}
+
+	public void setExternalUserType(String externalUserType) {
+		this.externalUserType = externalUserType;
+	}
+
+}
diff --git a/src/main/java/org/olat/modules/openmeetings/model/RoomReturnInfo.java b/src/main/java/org/olat/modules/openmeetings/model/RoomReturnInfo.java
new file mode 100644
index 00000000000..f29570af12d
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/model/RoomReturnInfo.java
@@ -0,0 +1,60 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * 12.10.2011 by frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.openmeetings.model;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public class RoomReturnInfo {
+
+		private long roomId;
+		private String name;
+		private int numOfUsers;
+		
+		public RoomReturnInfo() {
+			//
+		}
+		
+		public Long getRoomId() {
+			return roomId;
+		}
+		
+		public void setRoomId(long roomId) {
+			this.roomId = roomId;
+		}
+		
+		public String getName() {
+			return name;
+		}
+		
+		public void setName(String name) {
+			this.name = name;
+		}
+		
+		public int getNumOfUsers() {
+			return numOfUsers;
+		}
+		
+		public void setNumOfUsers(int numOfUsers) {
+			this.numOfUsers = numOfUsers;
+		}
+}
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminController.java
index 5aba0a31fe7..f698ac3ebd4 100644
--- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminController.java
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminController.java
@@ -43,11 +43,12 @@ public class OpenMeetingsAdminController extends BasicController  {
 
 	private final OpenMeetingsModule openMeetingsModule;
 
-	private final Link accountLink, bookingsLink;
+	private final Link accountLink, roomsLink;
 	private final SegmentViewComponent segmentView;
 	private final VelocityContainer mainVC;
 	
 	private OpenMeetingsConfigurationController configController;
+	private OpenMeetingsAdminRoomsController roomsController;
 	
 	public OpenMeetingsAdminController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl);
@@ -59,8 +60,8 @@ public class OpenMeetingsAdminController extends BasicController  {
 		accountLink = LinkFactory.createLink("openmeetings.account", mainVC, this);
 		segmentView.addSegment(accountLink, true);
 		
-		bookingsLink = LinkFactory.createLink("rooms.title", mainVC, this);
-		segmentView.addSegment(bookingsLink, false);
+		roomsLink = LinkFactory.createLink("rooms.title", mainVC, this);
+		segmentView.addSegment(roomsLink, false);
 		
 		doOpenAccountSettings(ureq);
 		
@@ -81,8 +82,8 @@ public class OpenMeetingsAdminController extends BasicController  {
 				Component clickedLink = mainVC.getComponent(segmentCName);
 				if (clickedLink == accountLink) {
 					doOpenAccountSettings(ureq);
-				} else if (clickedLink == bookingsLink){
-					//doOpenBookings(ureq);
+				} else if (clickedLink == roomsLink){
+					doOpenRooms(ureq);
 				}
 			}
 		}
@@ -96,5 +97,11 @@ public class OpenMeetingsAdminController extends BasicController  {
 		mainVC.put("segmentCmp", configController.getInitialComponent());
 	}
 	
-
+	private void doOpenRooms(UserRequest ureq) {
+		if(roomsController == null) {
+			roomsController = new OpenMeetingsAdminRoomsController(ureq, getWindowControl());
+			listenTo(roomsController);
+		} 
+		mainVC.put("segmentCmp", roomsController.getInitialComponent());
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomInfosController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomInfosController.java
new file mode 100644
index 00000000000..26622dc2a93
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomInfosController.java
@@ -0,0 +1,108 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * 12.10.2011 by frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.openmeetings.ui;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.components.link.LinkFactory;
+import org.olat.core.gui.components.segmentedview.SegmentViewComponent;
+import org.olat.core.gui.components.segmentedview.SegmentViewEvent;
+import org.olat.core.gui.components.segmentedview.SegmentViewFactory;
+import org.olat.core.gui.components.velocity.VelocityContainer;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.controller.BasicController;
+import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class OpenMeetingsAdminRoomInfosController extends BasicController {
+	
+	private final Link infosLink, membersLink;
+	private final SegmentViewComponent segmentView;
+	private final VelocityContainer mainVC;
+	
+	private OpenMeetingsAdminRoomRawInfosController infosController;
+	private OpenMeetingsAdminRoomMembersController membersController;
+	
+	private final OpenMeetingsRoom room;
+	
+	public OpenMeetingsAdminRoomInfosController(UserRequest ureq, WindowControl wControl, OpenMeetingsRoom room) {
+		super(ureq, wControl);
+		
+		this.room = room;
+		
+		mainVC = createVelocityContainer("room_admin");
+		
+		segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
+		infosLink = LinkFactory.createLink("room.infos", mainVC, this);
+		segmentView.addSegment(infosLink, true);
+		
+		membersLink = LinkFactory.createLink("users", mainVC, this);
+		segmentView.addSegment(membersLink, false);
+		
+		doOpenInfos(ureq);
+		
+		putInitialPanel(mainVC);
+		
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		if(source == segmentView) {
+			if(event instanceof SegmentViewEvent) {
+				SegmentViewEvent sve = (SegmentViewEvent)event;
+				String segmentCName = sve.getComponentName();
+				Component clickedLink = mainVC.getComponent(segmentCName);
+				if (clickedLink == infosLink) {
+					doOpenInfos(ureq);
+				} else if (clickedLink == membersLink){
+					doOpenMembers(ureq);
+				}
+			}
+		}
+	}
+	
+	private void doOpenInfos(UserRequest ureq) {
+		if(infosController == null) {
+			infosController = new OpenMeetingsAdminRoomRawInfosController(ureq, getWindowControl(), room);
+			listenTo(infosController);
+		} 
+		mainVC.put("segmentCmp", infosController.getInitialComponent());
+	}
+
+	private void doOpenMembers(UserRequest ureq) {
+		if(membersController == null) {
+			membersController = new OpenMeetingsAdminRoomMembersController(ureq, getWindowControl(), room);
+			listenTo(membersController);
+		} 
+		mainVC.put("segmentCmp", membersController.getInitialComponent());
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomMembersController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomMembersController.java
new file mode 100644
index 00000000000..2960c6a8899
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomMembersController.java
@@ -0,0 +1,224 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * 12.10.2011 by frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.openmeetings.ui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+import org.olat.core.CoreSpringFactory;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.table.ColumnDescriptor;
+import org.olat.core.gui.components.table.StaticColumnDescriptor;
+import org.olat.core.gui.components.table.TableController;
+import org.olat.core.gui.components.table.TableDataModel;
+import org.olat.core.gui.components.table.TableEvent;
+import org.olat.core.gui.components.table.TableGuiConfiguration;
+import org.olat.core.gui.components.table.TableMultiSelectEvent;
+import org.olat.core.gui.components.velocity.VelocityContainer;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.controller.BasicController;
+import org.olat.core.gui.translator.Translator;
+import org.olat.core.id.UserConstants;
+import org.olat.modules.openmeetings.manager.OpenMeetingsManager;
+import org.olat.modules.openmeetings.manager.OpenMeetingsException;
+import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+import org.olat.modules.openmeetings.model.OpenMeetingsUser;
+import org.olat.user.UserManager;
+import org.olat.user.propertyhandlers.UserPropertyHandler;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class OpenMeetingsAdminRoomMembersController extends BasicController {
+	
+	private final OpenMeetingsRoom room;
+	private final OpenMeetingsManager openMeetingsManager;
+
+	private final TableController tableCtr;
+	private final VelocityContainer mainVC;
+	
+	public OpenMeetingsAdminRoomMembersController(UserRequest ureq, WindowControl wControl, OpenMeetingsRoom room) {
+		super(ureq, wControl);
+
+		this.room = room;
+		openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class);
+
+		mainVC = createVelocityContainer("room_user_admin");
+
+		TableGuiConfiguration tableConfig = new TableGuiConfiguration();
+		tableConfig.setTableEmptyMessage(translate("users.empty"));
+		
+		Translator trans = UserManager.getInstance().getPropertyHandlerTranslator(getTranslator());
+		tableCtr = new TableController(tableConfig, ureq, getWindowControl(), trans);
+		listenTo(tableCtr);
+		
+		tableCtr.addColumnDescriptor(getColumnDescriptor(Col.firstName.ordinal(), UserConstants.FIRSTNAME, ureq.getLocale()));
+		tableCtr.addColumnDescriptor(getColumnDescriptor(Col.lastName.ordinal(), UserConstants.LASTNAME, ureq.getLocale()));
+		tableCtr.addColumnDescriptor(getColumnDescriptor(Col.email.ordinal(), UserConstants.EMAIL, ureq.getLocale()));
+		tableCtr.addColumnDescriptor(new StaticColumnDescriptor("kickout", "table.action", translate("kickout")));
+		
+		tableCtr.addMultiSelectAction("kickout", "kickout");
+		tableCtr.setMultiSelect(true);
+		
+		loadModel();
+		mainVC.put("userTable", tableCtr.getInitialComponent());
+		
+		putInitialPanel(mainVC);
+	}
+	
+	private ColumnDescriptor getColumnDescriptor(int pos, String attrName, Locale locale) {
+		List<UserPropertyHandler> userPropertyHandlers = UserManager.getInstance().getAllUserPropertyHandlers();
+		for(UserPropertyHandler handler:userPropertyHandlers) {
+			if(handler.getName().equals(attrName)) {
+				return handler.getColumnDescriptor(pos, null, locale);
+			}
+		}
+		return null;
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		//
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Controller source, Event event) {
+		if(source == tableCtr) {
+			if(event instanceof TableEvent) {
+				TableEvent e = (TableEvent)event;
+				int row = e.getRowId();
+				OpenMeetingsUser identity = (OpenMeetingsUser)tableCtr.getTableDataModel().getObject(row);
+				if("kickout".equals(e.getActionId())) {
+					signOut(Collections.singletonList(identity));
+				}
+			} else if(event instanceof TableMultiSelectEvent) {
+				TableMultiSelectEvent e = (TableMultiSelectEvent)event;
+				List<OpenMeetingsUser> identities = new ArrayList<OpenMeetingsUser>();
+				for (int i = e.getSelection().nextSetBit(0); i >= 0; i = e.getSelection().nextSetBit(i + 1)) {
+					OpenMeetingsUser identity = (OpenMeetingsUser)tableCtr.getTableDataModel().getObject(i);
+					identities.add(identity);
+				}
+				if("kickout".equals(e.getAction())) {
+					signOut(identities);
+				}
+			}
+			
+		}
+		super.event(ureq, source, event);
+	}
+	
+	private void signOut(List<OpenMeetingsUser> members) {
+		try {
+			for(OpenMeetingsUser member:members) {
+				if(openMeetingsManager.removeUser(member.getPublicSID())) {
+					showInfo("kickout.ok");
+				} else {
+					showInfo("kickout.nok");
+					break;
+				}
+			}
+			loadModel();
+		} catch (Exception e) {
+			showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
+		}
+	}
+
+	private void loadModel() {
+		try {
+			List<OpenMeetingsUser> users = openMeetingsManager.getUsersOf(room);
+			tableCtr.setTableDataModel(new UserToGroupDataModel(users));
+			
+			long numOfFreePlaces = room.getSize() - users.size();
+			mainVC.contextPut("freePlaces", new String[]{Long.toString(numOfFreePlaces)});
+		} catch (Exception e) {
+			showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
+		}
+	}
+
+	public class UserToGroupDataModel implements TableDataModel<OpenMeetingsUser> {
+		
+		private List<OpenMeetingsUser> members;
+		
+		public UserToGroupDataModel() {
+			//
+		}
+		
+		public UserToGroupDataModel( List<OpenMeetingsUser> members) {
+			this.members = members;
+		}
+
+		@Override
+		public int getColumnCount() {
+			return 4;
+		}
+
+		@Override
+		public int getRowCount() {
+			return members == null ? 0 : members.size();
+		}
+
+		@Override
+		public Object getValueAt(int row, int col) {
+			OpenMeetingsUser identity = getObject(row);
+			switch(Col.values()[col]) {
+				case firstName: return identity.getFirstName();
+				case lastName: return identity.getLastName();
+				case email: return identity.getExternalUserID();
+				default: {/* do nothing */}
+			}
+			return null;
+		}
+
+		@Override
+		public OpenMeetingsUser getObject(int row) {
+			return members.get(row);
+		}
+
+		@Override
+		public void setObjects(List<OpenMeetingsUser> objects) {
+			this.members = objects;
+		}
+
+		@Override
+		public Object createCopyWithEmptyList() {
+			return new UserToGroupDataModel();
+		}
+	}
+	
+	public enum Col {
+		firstName,
+		lastName,
+		email,
+		sign,
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomRawInfosController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomRawInfosController.java
new file mode 100644
index 00000000000..0ebe666cc82
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomRawInfosController.java
@@ -0,0 +1,63 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * 12.10.2011 by frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.openmeetings.ui;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class OpenMeetingsAdminRoomRawInfosController extends FormBasicController {
+	
+	private final OpenMeetingsRoom room;
+	
+	public OpenMeetingsAdminRoomRawInfosController(UserRequest ureq, WindowControl wControl, OpenMeetingsRoom room) {
+		super(ureq, wControl);
+		
+		this.room = room;
+		
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		uifactory.addStaticTextElement("room.name", room.getName(), formLayout);
+		uifactory.addStaticTextElement("room.size", Long.toString(room.getSize()), formLayout);
+
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+}
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomsController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomsController.java
new file mode 100644
index 00000000000..48d40406ded
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsAdminRoomsController.java
@@ -0,0 +1,211 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * 12.10.2011 by frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.openmeetings.ui;
+
+import java.util.List;
+
+import org.olat.NewControllerFactory;
+import org.olat.core.CoreSpringFactory;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.table.DefaultColumnDescriptor;
+import org.olat.core.gui.components.table.StaticColumnDescriptor;
+import org.olat.core.gui.components.table.TableController;
+import org.olat.core.gui.components.table.TableEvent;
+import org.olat.core.gui.components.table.TableGuiConfiguration;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.controller.BasicController;
+import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
+import org.olat.core.gui.control.generic.modal.DialogBoxController;
+import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
+import org.olat.core.id.OLATResourceable;
+import org.olat.core.id.context.BusinessControl;
+import org.olat.core.id.context.BusinessControlFactory;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.resource.OresHelper;
+import org.olat.modules.openmeetings.manager.OpenMeetingsManager;
+import org.olat.modules.openmeetings.manager.OpenMeetingsException;
+import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+import org.olat.properties.Property;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryManager;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class OpenMeetingsAdminRoomsController extends BasicController {
+	
+	private final OpenMeetingsManager openMeetingsManager;
+	
+	private Controller infoController;
+	private DialogBoxController dialogCtr;
+	private final TableController tableCtr;
+	private CloseableModalController cmc;
+	
+	public OpenMeetingsAdminRoomsController(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl);
+		
+		openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class);
+		
+		TableGuiConfiguration tableConfig = new TableGuiConfiguration();
+		tableConfig.setTableEmptyMessage(translate("table.empty"));
+		tableConfig.setDownloadOffered(true);
+		tableConfig.setColumnMovingOffered(false);
+		tableConfig.setSortingEnabled(true);
+		tableConfig.setDisplayTableHeader(true);
+		tableConfig.setDisplayRowCount(false);
+		tableConfig.setPageingEnabled(false);
+		
+		tableCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator());
+		listenTo(tableCtr);
+
+		tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("room.name", OpenMeetingsRoomsDataModel.Column.name.ordinal(), null, getLocale()));
+		tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("room.size", OpenMeetingsRoomsDataModel.Column.roomSize.ordinal(), null, getLocale()));
+		tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("room.numOfUsers", OpenMeetingsRoomsDataModel.Column.numOfUsers.ordinal(), null, getLocale()));
+		
+		tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("room.resource", OpenMeetingsRoomsDataModel.Column.resource.ordinal(), "resource", getLocale()));
+
+		tableCtr.addColumnDescriptor(new StaticColumnDescriptor("infos", "table.action", translate("room.infos")));
+		tableCtr.addColumnDescriptor(new StaticColumnDescriptor("delete", "table.action", translate("delete")));
+		
+		tableCtr.setSortColumn(0, false);
+
+		reloadModel();
+		
+		putInitialPanel(tableCtr.getInitialComponent());
+	}
+	
+	@Override
+	protected void doDispose() {
+		//auto disposed
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		//nothing to do
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Controller source, Event event) {
+		if(source == tableCtr) {
+			if(event instanceof TableEvent) {
+				TableEvent e = (TableEvent)event;
+				int row = e.getRowId();
+				OpenMeetingsRoom room = (OpenMeetingsRoom)tableCtr.getTableDataModel().getObject(row);
+				if("delete".equals(e.getActionId())) {
+					confirmDelete(ureq, room);
+				} else if("infos".equals(e.getActionId())) {
+					openInfoBox(ureq, room);
+				} else if("resource".equals(e.getActionId())) {
+					openResource(ureq, room);
+				}
+			}
+		} else if(source == dialogCtr) {
+			if (DialogBoxUIFactory.isOkEvent(event)) {
+				OpenMeetingsRoom room = (OpenMeetingsRoom)dialogCtr.getUserObject();
+				doDelete(room);
+			}
+		} else if (source == cmc ) {
+			removeAsListenerAndDispose(infoController);
+			removeAsListenerAndDispose(cmc);
+		} else if (source == infoController) {
+			cmc.deactivate();
+			removeAsListenerAndDispose(infoController);
+			removeAsListenerAndDispose(cmc);
+			reloadModel();
+		}
+	}
+	
+	protected void openResource(UserRequest ureq, OpenMeetingsRoom room) {
+		Property prop = room.getProperty();
+		if(prop != null) {
+			String url;
+			if(prop.getGrp() != null) {
+				url = "[BusinessGroup:" + prop.getGrp().getKey() + "]";
+			} else {
+				OLATResourceable ores = OresHelper.createOLATResourceableInstance(prop.getResourceTypeName(), prop.getResourceTypeId());
+				RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntry(ores, false);
+				if(re != null) {
+					url = "[RepositoryEntry:" + re.getKey() + "]";
+					if(StringHelper.containsNonWhitespace(prop.getName()) && "CourseModule".equals(ores.getResourceableTypeName())) {
+						url += "[CourseNode:" + prop.getName() + "]";
+					}	
+				} else {
+					showWarning("resource.dont.exist");
+					return;
+				}
+			}
+			BusinessControl bc = BusinessControlFactory.getInstance().createFromString(url);
+			WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl());
+			NewControllerFactory.getInstance().launch(ureq, bwControl);
+		}
+	}
+	
+	protected void openInfoBox(UserRequest ureq, OpenMeetingsRoom room) {
+		removeAsListenerAndDispose(infoController);
+		removeAsListenerAndDispose(cmc);
+		
+		try {
+			infoController = new OpenMeetingsAdminRoomInfosController(ureq, getWindowControl(), room);
+			listenTo(infoController);
+
+			cmc = new CloseableModalController(getWindowControl(), translate("close"), infoController.getInitialComponent(), true, translate("room.raw.title"));
+			listenTo(cmc);
+			cmc.activate();
+		} catch (Exception e) {
+			showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
+		}
+	}
+	
+	protected void doDelete(OpenMeetingsRoom room) {
+		try {
+			if(openMeetingsManager.deleteRoom(room)) {
+				showInfo("delete.ok");
+			} else {
+				showError("delete.nok");
+			}
+			reloadModel();
+		} catch (Exception e) {
+			showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
+		}
+	}
+	
+	protected void confirmDelete(UserRequest ureq, OpenMeetingsRoom room) {
+		String title = translate("delete");
+		String text = translate("delete.confirm", new String[]{ room.getName() });
+		dialogCtr = activateOkCancelDialog(ureq, title, text, dialogCtr);
+		dialogCtr.setUserObject(room);
+	}
+	
+	protected void reloadModel() {
+		try {
+			List<OpenMeetingsRoom> rooms = openMeetingsManager.getOpenOLATRooms();
+			OpenMeetingsRoomsDataModel tableModel = new OpenMeetingsRoomsDataModel(rooms);
+			tableCtr.setTableDataModel(tableModel);
+		} catch (Exception e) {
+			showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java
index 8b8350e46d9..37aa6dd7134 100644
--- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java
@@ -38,7 +38,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.util.StringHelper;
 import org.olat.modules.openmeetings.OpenMeetingsModule;
 import org.olat.modules.openmeetings.manager.OpenMeetingsManager;
-import org.olat.modules.openmeetings.manager.OpenMeetingsNotAvailableException;
+import org.olat.modules.openmeetings.manager.OpenMeetingsException;
 
 /**
  * 
@@ -97,6 +97,10 @@ public class OpenMeetingsConfigurationController extends FormBasicController {
 			loginEl = uifactory.addTextElement("openmeetings-login", "option.adminlogin", 32, login, moduleFlc);
 			String password = openMeetingsModule.getAdminPassword();
 			passwordEl = uifactory.addPasswordElement("openmeetings-password", "option.adminpassword", 32, password, moduleFlc);
+			
+			
+			String externalType = openMeetingsManager.getOpenOLATExternalType();
+			uifactory.addStaticTextElement("om.externaltype", "openolat.externaltype", externalType, moduleFlc);
 	
 			//buttons save - check
 			FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("save", getTranslator());
@@ -146,8 +150,8 @@ public class OpenMeetingsConfigurationController extends FormBasicController {
 					urlEl.setErrorKey("error.customerDoesntExist", null);
 					allOk = false;
 				}
-			} catch (OpenMeetingsNotAvailableException e) {
-				showError(OpenMeetingsNotAvailableException.I18N_KEY);
+			} catch (OpenMeetingsException e) {
+				showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
 			}
 		}
 		
@@ -218,8 +222,8 @@ public class OpenMeetingsConfigurationController extends FormBasicController {
 		} catch (NumberFormatException e) {
 			showError("error.customer.invalid");
 			return false;
-		} catch (OpenMeetingsNotAvailableException e) {
-			showError(OpenMeetingsNotAvailableException.I18N_KEY);
+		} catch (OpenMeetingsException e) {
+			showError(OpenMeetingsException.SERVER_NOT_I18N_KEY);
 			return false;
 		}
 	}
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java
index c5bb75e4582..db1342df086 100644
--- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java
@@ -31,6 +31,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.StringHelper;
 import org.olat.group.BusinessGroup;
+import org.olat.modules.openmeetings.manager.OpenMeetingsException;
 import org.olat.modules.openmeetings.manager.OpenMeetingsManager;
 import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
 import org.olat.modules.openmeetings.model.RoomType;
@@ -87,7 +88,11 @@ public class OpenMeetingsRoomEditController extends FormBasicController {
 		moderationModeValues = new String[]{ translate("room.moderation.yes"), translate("room.moderation.no") };
 		
 		openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class);
-		room = openMeetingsManager.getRoom(group, ores, subIdentifier);
+		try {
+			room = openMeetingsManager.getRoom(group, ores, subIdentifier);
+		} catch (OpenMeetingsException e) {
+			showError(e.getType().i18nKey());
+		}
 		initForm(ureq);
 	}
 
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomsDataModel.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomsDataModel.java
new file mode 100644
index 00000000000..d1b169b55f4
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomsDataModel.java
@@ -0,0 +1,125 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * 12.10.2011 by frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.openmeetings.ui;
+
+import java.util.List;
+
+import org.olat.core.gui.components.table.TableDataModel;
+import org.olat.core.util.StringHelper;
+import org.olat.modules.openmeetings.model.OpenMeetingsRoom;
+import org.olat.properties.Property;
+
+/**
+ * 
+ * Initial date: 08.11.2012<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class OpenMeetingsRoomsDataModel implements TableDataModel<OpenMeetingsRoom> {
+	
+	private List<OpenMeetingsRoom> rooms;
+	
+	
+	public OpenMeetingsRoomsDataModel() {
+		//
+	}
+	
+	public OpenMeetingsRoomsDataModel(List<OpenMeetingsRoom> rooms) {
+		this.rooms = rooms;
+	}
+	
+
+	@Override
+	public int getColumnCount() {
+		return 2;
+	}
+	
+	@Override
+	public int getRowCount() {
+		return rooms == null ? 0 : rooms.size();
+	}
+	
+	@Override
+	public OpenMeetingsRoom getObject(int row) {
+		return rooms.get(row);
+	}
+
+	@Override
+	public Object getValueAt(int row, int col) {
+		OpenMeetingsRoom room = getObject(row);
+		switch(Column.values()[col]) {
+			case name: {
+				String name = room.getName();
+				return name;
+			}
+
+			case roomSize: {
+				long roomSize = room.getSize();
+				if(roomSize > 0) {
+					return Long.toString(roomSize);
+				}
+				return "-";
+			}
+			case numOfUsers: {
+				int numOfUsers = room.getNumOfUsers();
+				if(numOfUsers > 0) {
+					return Integer.toString(numOfUsers);
+				}
+				return "-";
+			}
+			case resource: {
+				Property property = room.getProperty();
+				if(property == null) {
+					return "???";
+				} else if(property.getGrp() != null) {
+					return property.getGrp().getName();
+				} else if(StringHelper.containsNonWhitespace(property.getResourceTypeName())) {
+					return property.getResourceTypeName() + "(" + property.getResourceTypeId() + ")";
+				}
+				return "";
+			}
+
+
+			default: return "";
+		}
+	}
+
+	@Override
+	public void setObjects(List<OpenMeetingsRoom> objects) {
+		this.rooms = objects;
+	}
+
+	@Override
+	public Object createCopyWithEmptyList() {
+		return new OpenMeetingsRoomsDataModel();
+	}
+
+	public enum Column {
+		name,
+		begin,
+		end,
+		group,
+		roomSize,
+		numOfUsers,
+		resource,
+		open,
+		sign,
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java
index 94332c9a616..239b3860880 100644
--- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java
@@ -21,16 +21,21 @@ package org.olat.modules.openmeetings.ui;
 
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
 import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.media.RedirectMediaResource;
 import org.olat.core.id.OLATResourceable;
 import org.olat.group.BusinessGroup;
+import org.olat.modules.openmeetings.OpenMeetingsModule;
 import org.olat.modules.openmeetings.manager.OpenMeetingsManager;
-import org.olat.modules.openmeetings.manager.OpenMeetingsNotAvailableException;
+import org.olat.modules.openmeetings.manager.OpenMeetingsException;
 
 /**
  * 
@@ -40,13 +45,17 @@ import org.olat.modules.openmeetings.manager.OpenMeetingsNotAvailableException;
  */
 public class OpenMeetingsRunController extends FormBasicController {
 
+	private FormLink openLink;
+	
 	private final Long roomId;
+	private final OpenMeetingsModule openMeetingsModule;
 	private final OpenMeetingsManager openMeetingsManager;
 
 	public OpenMeetingsRunController(UserRequest ureq, WindowControl wControl, BusinessGroup group, OLATResourceable ores,
 			String subIdentifier, String resourceName, boolean admin) {
-		super(ureq, wControl);
-		
+		super(ureq, wControl, "room");
+
+		openMeetingsModule = CoreSpringFactory.getImpl(OpenMeetingsModule.class);
 		openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class);
 		roomId = openMeetingsManager.getRoomId(group, ores, subIdentifier);
 		
@@ -55,10 +64,23 @@ public class OpenMeetingsRunController extends FormBasicController {
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
-		FormLayoutContainer buttonsContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
-		formLayout.add(buttonsContainer);
-		uifactory.addFormSubmitButton("open.room", "open.room", buttonsContainer);
-		
+		if(formLayout instanceof FormLayoutContainer) {
+			FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
+			if(!openMeetingsModule.isEnabled()) {
+				layoutCont.contextPut("disabled", Boolean.TRUE);
+			} else if(roomId == null) {
+				layoutCont.contextPut("norroom", Boolean.TRUE);
+			} else {
+
+				FormLayoutContainer roomCont = FormLayoutContainer.createDefaultFormLayout("openroom", getTranslator());
+				layoutCont.add(roomCont);
+				
+				String name = "Hello";
+				uifactory.addStaticTextElement("room.name", "room.name", name, roomCont);
+				openLink = uifactory.addFormLink("open", "open.room", null, roomCont, Link.BUTTON);
+				((Link)openLink.getComponent()).setTarget("openmeetings");
+			}
+		}
 	}
 
 	@Override
@@ -72,15 +94,27 @@ public class OpenMeetingsRunController extends FormBasicController {
 			doOpenRoom(ureq);
 		}
 	}
-	
+
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if(source == openLink) {
+			doOpenRoom(ureq);
+		} else {
+			super.formInnerEvent(ureq, source, event);
+		}
+	}
+
 	private void doOpenRoom(UserRequest ureq) {	
+		if(roomId == null && roomId.longValue() <= 0) {
+		
+		}
 		try {
-			String securedHash = openMeetingsManager.setUser(getIdentity(), roomId);
+			String securedHash = openMeetingsManager.setUserToRoom(getIdentity(), roomId, true);
 			String url = openMeetingsManager.getURL(getIdentity(), roomId.longValue(), securedHash, getLocale());
 			RedirectMediaResource redirect = new RedirectMediaResource(url);
 			ureq.getDispatchResult().setResultingMediaResource(redirect);
-		} catch (Exception e) {
-			showError(OpenMeetingsNotAvailableException.I18N_KEY);
+		} catch (OpenMeetingsException e) {
+			showError(e.getType().i18nKey());
 		} 
 	}
 }
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html b/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html
new file mode 100644
index 00000000000..95e336c3fdc
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html
@@ -0,0 +1,7 @@
+#if($disabled)
+ <div class="b_warning">$r.translate("openmeetings.disabled.error")</div>
+#elseif($noroom)
+ <div class="b_warning">$r.translate("room.notfound.error")</div>
+#else
+	$r.render("openroom")
+#end
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_content/room_admin.html b/src/main/java/org/olat/modules/openmeetings/ui/_content/room_admin.html
new file mode 100644
index 00000000000..3d776f93825
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/_content/room_admin.html
@@ -0,0 +1,7 @@
+<div class="b_clearfix">
+	$r.render("segments") <br/>	
+		
+	#if($r.available("segmentCmp"))
+		$r.render("segmentCmp")
+	#end
+</div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_content/room_user_admin.html b/src/main/java/org/olat/modules/openmeetings/ui/_content/room_user_admin.html
new file mode 100644
index 00000000000..99bd0edff71
--- /dev/null
+++ b/src/main/java/org/olat/modules/openmeetings/ui/_content/room_user_admin.html
@@ -0,0 +1 @@
+$r.render("userTable")
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties
index 8789ea5e721..5a4ec02f113 100644
--- a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties
@@ -4,15 +4,24 @@ check=Serververbindung testen
 check.ok=Der Verbindungstest war erfolgreich, Sie k\u00F6nnen OpenMeetings nun benutzen.
 check.nok=Der Verbindungstest war nicht erfolgreich. Bitte pr\u00FCfen Sie die Server URL, der Benutzername und das Passwort des Systembenutzers!
 enabled=eingeschaltet
+error.notAvailable=Der Server ist nicht verfügbar,
+error.unkown=Unerwartet Fehler
+delete=Löschen
+delete.confirm=Wollen Sie wirklich diesen Raum "{0}" löschen?
+delete.ok=Der Raum würde erfolgreich gelöscht.
+delete.nok=Der Raum konnte nicht gelöscht werden.
+kickout=Kick out
+kickout.ok=Kick out
+kickout.nok=Kick out error
 openmeetings.account=Konfiguration
 openmeetings.title=OpenMeetings
-openmeetings.intro=Apache OpenMeetings v2.0 description
+openmeetings.intro=Apache OpenMeetings v2.0 Konfiguration
 openmeetings.module.enabled=Modul "OpenMeetings"
-rooms.title=Rooms
-
+table.empty=Kein Raum wurde gefunden.
+rooms.title=Raum
 room.comment=Kommentar
 room.name=Name des Raums
-room.type=Room type
+room.type=Typ von Raum
 room.type.conference=Conference
 room.type.audience=Audience
 room.type.restricted=Restricted
@@ -20,12 +29,19 @@ room.type.interview=Interview
 room.moderation.mode=Moderation
 room.moderation.yes=Moderated
 room.moderation.no=No moderation
-room.size=Room size
+room.size=Anzhal Benutzere
 room.recording=Recording
-
-open.room=Go go go
-
-option.baseurl=URL OpennMeetings Server
+room.resource=Ressourcen
+room.numOfUsers=#Benutzer
+room.infos=Detailinformationen
+open.room=Zum Raum gehen
+room.raw.title=Detailinformationen
+users=Benutzer
+users.empty=Der Raum ist noch leer
+openolat.externaltype=External type
+room.notfound.error=Der Raum wurd nicht gefunden
+openmeetings.disabled.error=Der Apache OpenMeetings Server ist nicht  verf\u00FCgbar
+option.baseurl=URL OpenMeetings Server
 option.adminlogin=Web Service Benutzername
 option.adminpassword=Web Service Passwort
 chelp.openmeetings1=Apache OpenMeetings Hilfe
-- 
GitLab