You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2017/01/24 17:38:20 UTC

svn commit: r1780097 [1/2] - in /openmeetings/application: branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/ branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/ branches/3.1.x/openme...

Author: solomax
Date: Tue Jan 24 17:38:20 2017
New Revision: 1780097

URL: http://svn.apache.org/viewvc?rev=1780097&view=rev
Log:
[OPENMEETINGS-1541] more fixes for calendar web service and tests

Added:
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java
Modified:
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
    openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java
    openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
    openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java
    openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
    openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java
    openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
    openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
    openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java
    openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java Tue Jan 24 17:38:20 2017
@@ -69,31 +69,30 @@ public class AppointmentDao {
 	/*
 	 * insert, update, delete, select
 	 */
-
 	// -----------------------------------------------------------------------------------------------
-
 	public Appointment get(Long id) {
 		TypedQuery<Appointment> query = em.createNamedQuery("getAppointmentById", Appointment.class);
 		query.setParameter("id", id);
 
-		Appointment appoint = null;
+		Appointment a = null;
 		try {
-			appoint = query.getSingleResult();
+			a = query.getSingleResult();
 		} catch (NoResultException ex) {
+			//no-op
 		}
-		return appoint;
+		return a;
 	}
 
 	public Appointment getAny(Long id) {
 		TypedQuery<Appointment> query = em.createNamedQuery("getAppointmentByIdAny", Appointment.class).setParameter("id", id);
 
-		Appointment appoint = null;
+		Appointment a = null;
 		try {
-			appoint = query.getSingleResult();
+			a = query.getSingleResult();
 		} catch (NoResultException ex) {
+			//no-op
 		}
-
-		return appoint;
+		return a;
 	}
 
 	public List<Appointment> get() {
@@ -103,7 +102,7 @@ public class AppointmentDao {
 	public Appointment update(Appointment a, Long userId) {
 		return update(a, userId, true);
 	}
-	
+
 	public Appointment update(Appointment a, Long userId, boolean sendmails) {
 		Room r = a.getRoom();
 		if (r.getId() == null) {
@@ -151,11 +150,11 @@ public class AppointmentDao {
 			em.persist(a);
 		} else {
 			a.setUpdated(new Date());
-			a =	em.merge(a);
+			a = em.merge(a);
 		}
 		return a;
 	}
-	
+
 	// ----------------------------------------------------------------------------------------------------------
 
 	public void delete(Appointment a, Long userId) {
@@ -167,7 +166,7 @@ public class AppointmentDao {
 		}
 		update(a, userId);
 	}
-	
+
 	public List<Appointment> getInRange(Long userId, Date start, Date end) {
 		log.debug("Start " + start + " End " + end);
 
@@ -175,8 +174,8 @@ public class AppointmentDao {
 		query.setParameter("start", start);
 		query.setParameter("end", end);
 		query.setParameter("userId", userId);
-		
-		List<Appointment> listAppoints = new ArrayList<Appointment>(query.getResultList()); 
+
+		List<Appointment> listAppoints = new ArrayList<>(query.getResultList());
 		TypedQuery<Appointment> q1 = em.createNamedQuery("joinedAppointmentsInRange", Appointment.class);
 		q1.setParameter("start", start);
 		q1.setParameter("end", end);
@@ -196,7 +195,7 @@ public class AppointmentDao {
 		q.setParameter("end", end.getTime());
 		return q.getResultList();
 	}
-	
+
 	// next appointment to select date
 	public Appointment getNext(Long userId, Date start) {
 		List<Appointment> list = em.createNamedQuery("getNextAppointment", Appointment.class)

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java Tue Jan 24 17:38:20 2017
@@ -36,6 +36,7 @@ import org.apache.openmeetings.db.dto.us
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.wicket.ajax.json.JSONObject;
 
 @XmlRootElement
@@ -92,7 +93,7 @@ public class AppointmentDTO implements S
 		reminderEmailSend = a.isReminderEmailSend();
 	}
 
-	public Appointment get(UserDao userDao, AppointmentDao appointmentDao) {
+	public Appointment get(UserDao userDao, AppointmentDao appointmentDao, User u) {
 		Appointment a = id == null ? new Appointment() : appointmentDao.get(id);
 		a.setId(id);
 		a.setTitle(title);
@@ -100,7 +101,7 @@ public class AppointmentDTO implements S
 		a.setStart(start.getTime());
 		a.setEnd(end.getTime());
 		a.setDescription(description);
-		a.setOwner(owner == null ? null : userDao.get(owner.getId()));
+		a.setOwner(owner == null ? u : userDao.get(owner.getId()));
 		a.setInserted(inserted);
 		a.setUpdated(updated);
 		a.setDeleted(deleted);
@@ -109,7 +110,7 @@ public class AppointmentDTO implements S
 		a.setIcalId(icalId);
 		a.setMeetingMembers(new ArrayList<MeetingMember>());
 		for(MeetingMemberDTO mm : meetingMembers) {
-			MeetingMember m = mm.get(userDao);
+			MeetingMember m = mm.get(userDao, u);
 			m.setAppointment(a);
 			a.getMeetingMembers().add(m);
 		}

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.db.dto.calendar;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
+
 import java.io.Serializable;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -44,7 +46,7 @@ public class MeetingMemberDTO implements
 		this.user = new UserDTO(mm.getUser());
 	}
 
-	public MeetingMember get(UserDao userDao) {
+	public MeetingMember get(UserDao userDao, User owner) {
 		MeetingMember mm = new MeetingMember();
 		mm.setId(id);
 		if (user.getId() != null) {
@@ -55,6 +57,14 @@ public class MeetingMemberDTO implements
 				// try to get ext. user
 				u = userDao.getExternalUser(user.getExternalId(), user.getExternalType());
 			}
+			if (u == null && user.getAddress() != null) {
+				u = userDao.getContact(user.getAddress().getEmail()
+						, user.getFirstname()
+						, user.getLastname()
+						, user.getLanguageId()
+						, user.getTimeZoneId()
+						, owner);
+			}
 			if (u == null) {
 				u = user.get(userDao);
 				u.setType(User.Type.contact);
@@ -85,8 +95,7 @@ public class MeetingMemberDTO implements
 
 	public static MeetingMemberDTO get(JSONObject o) {
 		MeetingMemberDTO m = new MeetingMemberDTO();
-		long id = o.optLong("id");
-		m.id = id == 0 ? null : id;
+		m.id = optLong(o, "id");
 		m.user = UserDTO.get(o.optJSONObject("user"));
 		return m;
 	}

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java Tue Jan 24 17:38:20 2017
@@ -19,6 +19,8 @@
 package org.apache.openmeetings.db.dto.room;
 
 import static org.apache.openmeetings.db.dto.room.RoomOptionsDTO.optInt;
+import static org.apache.openmeetings.db.util.DtoHelper.optEnum;
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -349,11 +351,10 @@ public class RoomDTO implements Serializ
 			return null;
 		}
 		RoomDTO r = new RoomDTO();
-		long id = o.optLong("id");
-		r.id = id == 0 ? null : id;
+		r.id = optLong(o, "id");
 		r.name = o.optString("name");
 		r.comment = o.optString("comment");
-		r.type = Room.Type.valueOf(o.getString("type"));
+		r.type = optEnum(Room.Type.class, o, "type");
 		r.numberOfPartizipants = o.optLong("numberOfPartizipants", 4);
 		r.appointment = o.optBoolean("appointment", false);
 		r.confno = o.optString("confno");

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.db.dto.room;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
+
 import java.io.Serializable;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -99,11 +101,7 @@ public class RoomOptionsDTO implements S
 	public static Integer optInt(JSONObject o, String key) {
 		return o.has(key) && !o.isNull(key) ? o.getInt(key) : null;
 	}
-	
-	public static Long optLong(JSONObject o, String key) {
-		return o.has(key) && !o.isNull(key) ? o.getLong(key) : null;
-	}
-	
+
 	public static RoomOptionsDTO fromString(String s) {
 		JSONObject o = new JSONObject(s);
 		RoomOptionsDTO ro = new RoomOptionsDTO();
@@ -116,7 +114,7 @@ public class RoomOptionsDTO implements S
 		ro.showNickNameDialog = o.optBoolean("showNickNameDialog", false);
 		return ro;
 	}
-	
+
 	@Override
 	public String toString() {
 		return new JSONObject(this).toString();

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,10 @@
  */
 package org.apache.openmeetings.db.dto.user;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optEnum;
+import static org.apache.openmeetings.db.util.DtoHelper.optEnumList;
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
+
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -191,30 +195,23 @@ public class UserDTO implements Serializ
 			return null;
 		}
 		UserDTO u = new UserDTO();
-		long id = o.optLong("id");
-		u.id = id == 0 ? null : id;
+		u.id = optLong(o, "id");
 		u.login = o.optString("login");
 		u.password = o.optString("password");
 		u.firstname = o.optString("firstname");
 		u.lastname = o.optString("lastname");
-		JSONArray rr = o.optJSONArray("rights");
-		if (rr !=  null) {
-			for (int i = 0; i < rr.length(); ++i) {
-				u.rights.add(Right.valueOf(rr.getString(i)));
-			}
-		}
+		u.rights.addAll(optEnumList(Right.class, o.optJSONArray("rights")));
 		u.languageId = o.optLong("languageId");
 		JSONObject a = o.optJSONObject("address");
 		if (a != null) {
-			u.address.setId(a.optLong("id"));
+			u.address.setId(optLong(a, "id"));
 			u.address.setCountry(a.optString("country"));
 			u.address.setEmail(a.optString("email"));
 		}
 		u.timeZoneId = o.optString("timeZoneId");
 		u.externalId = o.optString("externalId");
 		u.externalType = o.optString("externalType");
-		String t = o.optString("type", null);
-		u.type = t == null ? null : Type.valueOf(t);
+		u.type = optEnum(Type.class, o, "type");
 		return u;
 	}
 

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java Tue Jan 24 17:38:20 2017
@@ -36,56 +36,55 @@ import org.simpleframework.xml.Root;
 @Table(name = "address")
 @Root(name="address")
 public class Address implements IDataProviderEntity {
-
 	private static final long serialVersionUID = 1L;
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	@Column(name = "id")
 	private Long id;
-	
+
 	@Column(name = "additionalname")
 	@Element(data=true, required=false)
 	private String additionalname;
-	
+
 	@Lob
 	@Column(name = "comment", length=2048)
 	@Element(data=true, required=false)
 	private String comment;
-	
+
 	@Column(name = "fax")
 	@Element(data=true, required=false)
 	private String fax;
-	
+
 	@Column(name = "inserted")
 	@Element(name = "starttime",data=true, required=false)
 	private Date inserted;
-	
+
 	@Column(name = "country")
 	@Element(name="country", data=true, required=false)
 	private String country;
-	
+
 	@Column(name = "street")
 	@Element(data=true, required=false)
 	private String street;
-	
+
 	@Column(name = "town")
 	@Element(data=true, required=false)
 	private String town;
-	
+
 	@Column(name = "updated")
 	private Date updated;
-	
+
 	@Column(name = "zip")
 	@Element(data=true, required=false)
 	private String zip;
-	
+
 	@Column(name = "deleted", nullable = false)
 	private boolean deleted;
 
 	@Column(name = "email")
 	@Element(name="mail", data=true, required=false)
 	private String email;
-	
+
 	@Column(name = "phone")
 	@Element(data=true, required=false)
 	private String phone;

Added: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java?rev=1780097&view=auto
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java (added)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java Tue Jan 24 17:38:20 2017
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.db.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.wicket.ajax.json.JSONArray;
+import org.apache.wicket.ajax.json.JSONObject;
+
+public class DtoHelper {
+	public static Long optLong(JSONObject o, String key) {
+		return o.has(key) && !o.isNull(key) ? o.getLong(key) : null;
+	}
+
+	public static <T extends Enum<T>> T optEnum(Class<T> clazz, JSONObject o, String key) {
+		return o.has(key) && !o.isNull(key) ? Enum.valueOf(clazz, o.getString(key)) : null;
+	}
+
+	public static <T extends Enum<T>> Collection<T> optEnumList(Class<T> clazz, JSONArray arr) {
+		Collection<T> l = new ArrayList<>();
+		if (arr !=  null) {
+			for (int i = 0; i < arr.length(); ++i) {
+				l.add(Enum.valueOf(clazz, arr.getString(i)));
+			}
+		}
+		return l;
+	}
+}

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Tue Jan 24 17:38:20 2017
@@ -96,7 +96,7 @@ import org.wicketstuff.dashboard.web.Das
 public class Application extends AuthenticatedWebApplication implements IApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static ConcurrentHashMap<String, Client> ONLINE_USERS = new ConcurrentHashMap<>(); 
+	private static ConcurrentHashMap<String, Client> ONLINE_USERS = new ConcurrentHashMap<>();
 	private static ConcurrentHashMap<String, Client> INVALID_SESSIONS = new ConcurrentHashMap<>();
 	private static ConcurrentHashMap<Long, Set<String>> ROOMS = new ConcurrentHashMap<>();
 	//additional maps for faster searching should be created
@@ -114,14 +114,14 @@ public class Application extends Authent
 		wicketApplicationName = super.getName();
 		getSecuritySettings().setAuthenticationStrategy(new OmAuthenticationStrategy());
 		getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);
-		
-		//Add custom resource loader at the beginning, so it will be checked first in the 
-		//chain of Resource Loaders, if not found it will search in Wicket's internal 
+
+		//Add custom resource loader at the beginning, so it will be checked first in the
+		//chain of Resource Loaders, if not found it will search in Wicket's internal
 		//Resource Loader for a the property key
 		getResourceSettings().getStringResourceLoaders().add(0, new LabelResourceLoader());
-		
+
 		super.init();
-		
+
 		// register some widgets
 		dashboardContext = new DashboardContext();
 		dashboardContext.setDashboardPersister(new UserDashboardPersister());
@@ -136,7 +136,7 @@ public class Application extends Authent
 		DashboardSettings dashboardSettings = DashboardSettings.get();
 		dashboardSettings.setIncludeJQuery(false);
 		dashboardSettings.setIncludeJQueryUI(false);
-		
+
 		getRootRequestMapperAsCompound().add(new NoVersionMapper(getHomePage()));
 		getRootRequestMapperAsCompound().add(new NoVersionMapper("notinited", NotInitedPage.class));
 		getRootRequestMapperAsCompound().add(new NoVersionMapper("swf", HashPage.class));
@@ -157,7 +157,7 @@ public class Application extends Authent
 		public NoVersionMapper(final Class<? extends IRequestablePage> pageClass) {
 			this("/", pageClass);
 		}
-		
+
 		public NoVersionMapper(String mountPath, final Class<? extends IRequestablePage> pageClass) {
 			super(mountPath, pageClass, new PageParametersEncoder());
 		}
@@ -166,7 +166,7 @@ public class Application extends Authent
 		protected void encodePageComponentInfo(Url url, PageComponentInfo info) {
 			//Does nothing
 		}
-		
+
 		@Override
 		public Url mapHandler(IRequestHandler requestHandler) {
 			if (requestHandler instanceof ListenerInterfaceRequestHandler || requestHandler instanceof BookmarkableListenerInterfaceRequestHandler) {
@@ -180,7 +180,7 @@ public class Application extends Authent
 	public static OmAuthenticationStrategy getAuthenticationStrategy() {
 		return (OmAuthenticationStrategy)get().getSecuritySettings().getAuthenticationStrategy();
 	}
-	
+
 	@Override
 	public Class<? extends Page> getHomePage() {
 		return MainPage.class;
@@ -195,31 +195,31 @@ public class Application extends Authent
 	public Class<? extends WebPage> getSignInPageClass() {
 		return SignInPage.class;
 	}
-	
+
 	public static Application get() {
 		return (Application) WebApplication.get();
 	}
-	
+
 	public static DashboardContext getDashboardContext() {
 		return get().dashboardContext;
 	}
-	
+
 	public static void addOnlineUser(Client c) {
 		log.debug("Adding online client: {}, room: {}", c.getUid(), c.getRoomId());
 		ONLINE_USERS.put(c.getUid(), c);
 	}
-	
+
 	public static void removeOnlineUser(Client c) {
 		if (c != null) {
 			log.debug("Removing online client: {}, room: {}", c.getUid(), c.getRoomId());
 			ONLINE_USERS.remove(c.getUid());
 		}
 	}
-	
+
 	public static Client getOnlineClient(String uid) {
 		return uid == null ? null : ONLINE_USERS.get(uid);
 	}
-	
+
 	public static boolean isUserOnline(Long userId) {
 		boolean isUserOnline = false;
 		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
@@ -227,7 +227,7 @@ public class Application extends Authent
 				isUserOnline = true;
 				break;
 			}
-		} 
+		}
 		return isUserOnline;
 	}
 
@@ -245,11 +245,11 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static int getClientsSize() {
 		return ONLINE_USERS.size();
 	}
-	
+
 	public static Client getClientByKeys(Long userId, String sessionId) {
 		Client client = null;
 		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
@@ -258,10 +258,10 @@ public class Application extends Authent
 				client = c;
 				break;
 			}
-		} 
+		}
 		return client;
 	}
-	
+
 	@Override
 	public void invalidateClient(Long userId, String sessionId) {
 		Client client = getClientByKeys(userId, sessionId);
@@ -272,24 +272,24 @@ public class Application extends Authent
 			}
 		}
 	}
-	
+
 	public static boolean isInvaldSession(String sessionId) {
 		return sessionId == null ? false : INVALID_SESSIONS.containsKey(sessionId);
 	}
-	
+
 	public static void removeInvalidSession(String sessionId) {
 		if (sessionId != null){
 			INVALID_SESSIONS.remove(sessionId);
 		}
 	}
-	
+
 	public static Client addUserToRoom(Client c) {
 		log.debug("Adding online room client: {}, room: {}", c.getUid(), c.getRoomId());
 		ROOMS.putIfAbsent(c.getRoomId(), new ConcurrentHashSet<String>());
 		ROOMS.get(c.getRoomId()).add(c.getUid());
 		return c;
 	}
-	
+
 	public static Client removeUserFromRoom(Client c) {
 		log.debug("Removing online room client: {}, room: {}", c.getUid(), c.getRoomId());
 		if (c.getRoomId() != null) {
@@ -301,7 +301,7 @@ public class Application extends Authent
 		}
 		return c;
 	}
-	
+
 	public static List<Client> getRoomClients(Long roomId) {
 		List<Client> clients = new ArrayList<>();
 		if (roomId != null) {
@@ -317,7 +317,7 @@ public class Application extends Authent
 		}
 		return clients;
 	}
-	
+
 	public static Set<Long> getUserRooms(Long userId) {
 		Set<Long> result = new HashSet<>();
 		for (Entry<Long, Set<String>> me : ROOMS.entrySet()) {
@@ -330,7 +330,7 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static boolean isUserInRoom(long roomId, long userId) {
 		Set<String> clients = ROOMS.get(roomId);
 		if (clients != null) {
@@ -342,7 +342,7 @@ public class Application extends Authent
 		}
 		return false;
 	}
-	
+
 	//TODO need more safe way FIXME
 	public <T> T _getBean(Class<T> clazz) {
 		WebApplicationContext wac = getWebApplicationContext(getServletContext());
@@ -364,15 +364,15 @@ public class Application extends Authent
 		}
 		return loc;
 	}
-	
+
 	public static String getString(String key, final long languageId) {
 		return getString(key, getLocale(languageId));
 	}
-	
+
 	public static String getString(long id, final long languageId) {
 		return getString(id, getLocale(languageId));
 	}
-	
+
 	public static String getString(long id, final Locale loc) {
 		return getString("" + id, loc);
 	}
@@ -406,7 +406,7 @@ public class Application extends Authent
 		}
 		return result;
 	}
-	
+
 	public static <T> T getBean(Class<T> clazz) {
 		if (InitializationContainer.initComplete) {
 			if (!isInstalled()) {
@@ -417,7 +417,7 @@ public class Application extends Authent
 			throw new RestartResponseException(NotInitedPage.class);
 		}
 	}
-	
+
 	@Override
 	public <T> T getOmBean(Class<T> clazz) { //FIXME hack for email templates support (should be in separate module for now
 		return Application.getBean(clazz);
@@ -437,19 +437,23 @@ public class Application extends Authent
 		Room r = i.getRoom();
 		User u = i.getInvitee();
 		if (r != null) {
-			boolean allowed = u.getType() != Type.contact;
-			if (allowed) {
-				allowed = getBean(MainService.class).isRoomAllowedToUser(r, u);
-			}
-			if (!allowed) {
-				PageParameters pp = new PageParameters();
-				pp.add(INVITATION_HASH, i.getHash());
-				if (u.getLanguageId() > 0) {
-					pp.add("language", u.getLanguageId());
-				}
-				link = urlForPage(HashPage.class, pp);
-			} else {
+			if (r.isAppointment() && i.getInvitedBy().getId().equals(u.getId())) {
 				link = getRoomUrlFragment(r.getId()).getLink();
+			} else {
+				boolean allowed = u.getType() != Type.contact;
+				if (allowed) {
+					allowed = getBean(MainService.class).isRoomAllowedToUser(r, u);
+				}
+				if (allowed) {
+					link = getRoomUrlFragment(r.getId()).getLink();
+				} else {
+					PageParameters pp = new PageParameters();
+					pp.add(INVITATION_HASH, i.getHash());
+					if (u.getLanguageId() > 0) {
+						pp.add("language", u.getLanguageId());
+					}
+					link = urlForPage(HashPage.class, pp);
+				}
 			}
 		}
 		Recording rec = i.getRecording();
@@ -458,12 +462,12 @@ public class Application extends Authent
 		}
 		return link;
 	}
-	
+
 	@Override
 	public String getOmInvitationLink(Invitation i) { //FIXME hack for email templates support (should be in separate module for now
 		return getInvitationLink(i);
 	}
-	
+
 	public static String urlForPage(Class<? extends Page> clazz, PageParameters pp) {
 		RequestCycle rc = RequestCycle.get();
 		return rc.getUrlRenderer().renderFullUrl(Url.parse(getBean(ConfigurationDao.class).getBaseUrl() + rc.urlFor(clazz, pp)));
@@ -478,7 +482,7 @@ public class Application extends Authent
 	public String getOmString(long id) {
 		return getString(id);
 	}
-	
+
 	@Override
 	public String getOmString(long id, long languageId) {
 		return getString(id, languageId);

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java Tue Jan 24 17:38:20 2017
@@ -87,7 +87,7 @@ public abstract class InvitationForm ext
 		add(subject, message);
 		recipients.setLabel(Model.of(Application.getString(216))).setRequired(true).add(new AjaxFormComponentUpdatingBehavior("change") {
 			private static final long serialVersionUID = 1L;
-			
+
 			@Override
 			protected void onUpdate(AjaxRequestTarget target) {
 				url.setModelObject(null);
@@ -154,11 +154,11 @@ public abstract class InvitationForm ext
 		i.setId(null);
 		i.setUpdated(null);
 		i.setUsed(false);
-		
+
 		i.setPassword(CryptProvider.get().hash(i.getPassword()));
 		i.setValidFrom(getDate(from.getModelObject().minusMinutes(5), timeZoneId.getModelObject()));
 		i.setValidTo(getDate(to.getModelObject(), timeZoneId.getModelObject()));
-		
+
 		i.setInvitee(u);
 		i.setHash(UUID.randomUUID().toString());
 		if (Type.contact == u.getType()) {

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java Tue Jan 24 17:38:20 2017
@@ -48,7 +48,7 @@ public abstract class AbstractJUnitDefau
 	private static final String orgname = "smoketest";
 	private static final String timeZone = "Europe/Berlin";
 	private static final String useremail = "junit@openmeetings.apache.org";
-	
+
 	@Autowired
 	private AppointmentDao appointmentDao;
 	@Autowired
@@ -114,7 +114,7 @@ public abstract class AbstractJUnitDefau
 		if (ap.getReminder() == null) {
 			ap.setReminder(Appointment.Reminder.none);
 		}
-		
+
 		if (r == null) {
 			r = new Room();
 			r.setType(Room.Type.conference);
@@ -178,12 +178,15 @@ public abstract class AbstractJUnitDefau
 		importInitvalues.loadAll(cfg, false);
 	}
 
+	public User getContact(String uuid, Long ownerId) {
+		return userDao.getContact("email" + uuid, "firstname" + uuid, "lastname" + uuid, ownerId);
+	}
+
 	public User createUserContact(Long ownerId) {
-		return createUserContact(UUID.randomUUID().toString(), ownerId);
+		return createUserContact(getContact(UUID.randomUUID().toString(), ownerId), ownerId);
 	}
 
-	public User createUserContact(String uuid, Long ownerId) {
-		User user = userDao.getContact("email" + uuid, "firstname" + uuid, "lastname" + uuid, ownerId);
+	public User createUserContact(User user, Long ownerId) {
 		user = userDao.update(user, ownerId);
 		assertNotNull("Cann't add user", user);
 		return user;

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java Tue Jan 24 17:38:20 2017
@@ -19,14 +19,28 @@
 package org.apache.openmeetings.test.calendar;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
 
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
+import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
+import org.apache.openmeetings.db.entity.calendar.MeetingMember;
+import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.service.calendar.AppointmentLogic;
 import org.apache.openmeetings.test.AbstractWicketTester;
+import org.apache.openmeetings.web.app.WebSession;
+import org.apache.wicket.util.string.StringValue;
 import org.junit.Test;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -39,11 +53,17 @@ public class TestAppointmentAddAppointme
 	private AppointmentLogic appointmentLogic;
 	@Autowired
 	private AppointmentDao appointmentDao;
+	@Autowired
+	private UserDao userDao;
+
+	private void setTime(Appointment a) {
+		a.setStart(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));
+		a.setEnd(Date.from(LocalDateTime.now().plusHours(1).atZone(ZoneId.systemDefault()).toInstant()));
+	}
 
 	@Test
 	public void saveAppointment() throws Exception {
-		log.debug("- 1 MeetingReminderJob.execute");
-		log.warn("- 2 MeetingReminderJob.execute");
+		log.debug("- saveAppointment");
 
 		Calendar start = Calendar.getInstance();
 		start.setTimeInMillis(start.getTimeInMillis() + 600000);
@@ -74,14 +94,45 @@ public class TestAppointmentAddAppointme
 				isMonthly, isYearly, remind, mmClient,
 				roomType, languageId, false, "", -1, userId);
 		a = appointmentDao.update(a, userId);
-		
+
 		Thread.sleep(3000);
-		
+
 		appointmentLogic.doScheduledMeetingReminder();
-		
+
 		Thread.sleep(3000);
-		
-		assertTrue("Saved appointment should have valid id: " + a.getId(), a.getId() != null && a.getId() > 0);
+
+		assertNotNull("Saved appointment should have valid id: " + a.getId(), a.getId());
+	}
+
+	@Test
+	public void testCreate() {
+		Appointment a = new Appointment();
+		a.setTitle("Test title");
+		setTime(a);
+		a.setReminder(Reminder.ical);
+		a.setMeetingMembers(new ArrayList<>());
+		User owner = userDao.get(1L);
+		a.setOwner(owner);
+		a.setRoom(new Room());
+		a.getRoom().setAppointment(true);
+		a.getRoom().setType(Room.Type.conference);
+		for (int i = 0; i < 3; ++i) {
+			MeetingMember mm = new MeetingMember();
+			mm.setUser(getContact(UUID.randomUUID().toString(), owner.getId()));
+			a.getMeetingMembers().add(mm);
+		}
+		a = appointmentDao.update(a, owner.getId());
+		assertNotNull("Saved appointment should have valid id: " + a.getId(), a.getId());
+		assertEquals("Saved appointment should have corect count of guests: ", 3, a.getMeetingMembers().size());
+		for (MeetingMember mm : a.getMeetingMembers()) {
+			assertNotNull("Saved guest should have valid id: ", mm.getId());
+			assertNotNull("Saved guest should have valid invitation: ", mm.getInvitation());
+		}
+
+		WebSession ws = WebSession.get();
+		Appointment a1 = appointmentDao.get(a.getId());
+		ws.checkHashes(StringValue.valueOf(""), StringValue.valueOf(a1.getMeetingMembers().get(0).getInvitation().getHash()));
+		assertTrue("Login via secure hash should be successful", ws.isSignedIn());
 	}
 
 	private static String createClientObj(String firstname, String lastname, String email, String jNameTimeZone) {
@@ -94,5 +145,4 @@ public class TestAppointmentAddAppointme
 			.append(jNameTimeZone);
 		return sb.toString();
 	}
-
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java Tue Jan 24 17:38:20 2017
@@ -32,6 +32,7 @@ import org.apache.openmeetings.db.dao.ro
 import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dto.basic.ServiceResult;
 import org.apache.openmeetings.db.dto.calendar.AppointmentDTO;
+import org.apache.openmeetings.db.dto.calendar.MeetingMemberDTO;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.GroupUser;
@@ -174,14 +175,14 @@ public class TestCalendarService extends
 		JSONObject o = createAppointment()
 				.put("meetingMembers", new JSONArray()
 						.put(new JSONObject().put("user", new JSONObject()
-								.put("firstname", "Jhon 1")
+								.put("firstname", "John 1")
 								.put("lastname", "Doe")
-								.put("Address", new JSONObject().put("email", "jhon1@doe.email"))
+								.put("address", new JSONObject().put("email", "jhon1@doe.email"))
 								))
 						.put(new JSONObject().put("user", new JSONObject()
-								.put("firstname", "Jhon 2")
+								.put("firstname", "John 2")
 								.put("lastname", "Doe")
-								.put("Address", new JSONObject().put("email", "jhon2@doe.email"))
+								.put("address", new JSONObject().put("email", "jhon2@doe.email"))
 								))
 						);
 
@@ -202,6 +203,9 @@ public class TestCalendarService extends
 		assertNotNull("Valid DTO should be returned", dto);
 		assertNotNull("DTO id should be valid", dto.getId());
 		assertEquals("DTO should have 2 attendees", 2, dto.getMeetingMembers().size());
+		for (MeetingMemberDTO mm : dto.getMeetingMembers()) {
+			assertNotNull("Email should be valid", mm.getUser().getAddress().getEmail());
+		}
 
 		//try to change MM list
 		JSONObject o1 = AppointmentParamConverter.json(dto)

Modified: openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java Tue Jan 24 17:38:20 2017
@@ -302,10 +302,7 @@ public class CalendarWebService {
 				throw new ServiceException("Insufficient permissions"); //TODO code -26
 			}
 			if (AuthLevelUtil.hasUserLevel(u.getRights())) {
-				Appointment a = appointment.get(userDao, appointmentDao);
-				if (a.getOwner() == null) {
-					a.setOwner(u);
-				}
+				Appointment a = appointment.get(userDao, appointmentDao, u);
 				if (a.getRoom().getId() != null) {
 					if (a.getRoom().isAppointment()) {
 						a.getRoom().setIspublic(false);

Modified: openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.webservice.util;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optEnum;
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
 import static org.apache.openmeetings.util.CalendarPatterns.ISO8601_FULL_FORMAT;
 
 import java.util.Date;
@@ -37,8 +39,7 @@ public class AppointmentParamConverter i
 	public AppointmentDTO fromString(String val) {
 		JSONObject o = new JSONObject(val);
 		AppointmentDTO a = new AppointmentDTO();
-		long id = o.optLong("id");
-		a.setId(id == 0 ? null : id);
+		a.setId(optLong(o, "id"));
 		a.setTitle(o.optString("title"));
 		a.setLocation(o.optString("location"));
 		a.setOwner(UserDTO.get(o.optJSONObject("owner")));
@@ -49,8 +50,7 @@ public class AppointmentParamConverter i
 		a.setInserted(DateParamConverter.get(o.optString("inserted")));
 		a.setUpdated(DateParamConverter.get(o.optString("updated")));
 		a.setDeleted(o.optBoolean("inserted"));
-		String r = o.optString("reminder", null);
-		a.setReminder(r == null ? null : Reminder.valueOf(r));
+		a.setReminder(optEnum(Reminder.class, o, "reminder"));
 		a.setRoom(RoomDTO.get(o.optJSONObject("room")));
 		a.setIcalId(o.optString("icalId"));
 		JSONArray mm = o.optJSONArray("meetingMembers");

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java Tue Jan 24 17:38:20 2017
@@ -69,9 +69,7 @@ public class AppointmentDao {
 	/*
 	 * insert, update, delete, select
 	 */
-
 	// -----------------------------------------------------------------------------------------------
-
 	public Appointment get(Long id) {
 		TypedQuery<Appointment> query = em.createNamedQuery("getAppointmentById", Appointment.class);
 		query.setParameter("id", id);
@@ -94,7 +92,6 @@ public class AppointmentDao {
 		} catch (NoResultException ex) {
 			//no-op
 		}
-
 		return a;
 	}
 
@@ -153,7 +150,7 @@ public class AppointmentDao {
 			em.persist(a);
 		} else {
 			a.setUpdated(new Date());
-			a =	em.merge(a);
+			a = em.merge(a);
 		}
 		return a;
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java Tue Jan 24 17:38:20 2017
@@ -36,6 +36,7 @@ import org.apache.openmeetings.db.dto.us
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.wicket.ajax.json.JSONObject;
 
 @XmlRootElement
@@ -92,7 +93,7 @@ public class AppointmentDTO implements S
 		reminderEmailSend = a.isReminderEmailSend();
 	}
 
-	public Appointment get(UserDao userDao, AppointmentDao appointmentDao) {
+	public Appointment get(UserDao userDao, AppointmentDao appointmentDao, User u) {
 		Appointment a = id == null ? new Appointment() : appointmentDao.get(id);
 		a.setId(id);
 		a.setTitle(title);
@@ -100,7 +101,7 @@ public class AppointmentDTO implements S
 		a.setStart(start.getTime());
 		a.setEnd(end.getTime());
 		a.setDescription(description);
-		a.setOwner(owner == null ? null : userDao.get(owner.getId()));
+		a.setOwner(owner == null ? u : userDao.get(owner.getId()));
 		a.setInserted(inserted);
 		a.setUpdated(updated);
 		a.setDeleted(deleted);
@@ -109,7 +110,7 @@ public class AppointmentDTO implements S
 		a.setIcalId(icalId);
 		a.setMeetingMembers(new ArrayList<MeetingMember>());
 		for(MeetingMemberDTO mm : meetingMembers) {
-			MeetingMember m = mm.get(userDao);
+			MeetingMember m = mm.get(userDao, u);
 			m.setAppointment(a);
 			a.getMeetingMembers().add(m);
 		}

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.db.dto.calendar;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
+
 import java.io.Serializable;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -44,7 +46,7 @@ public class MeetingMemberDTO implements
 		this.user = new UserDTO(mm.getUser());
 	}
 
-	public MeetingMember get(UserDao userDao) {
+	public MeetingMember get(UserDao userDao, User owner) {
 		MeetingMember mm = new MeetingMember();
 		mm.setId(id);
 		if (user.getId() != null) {
@@ -55,6 +57,14 @@ public class MeetingMemberDTO implements
 				// try to get ext. user
 				u = userDao.getExternalUser(user.getExternalId(), user.getExternalType());
 			}
+			if (u == null && user.getAddress() != null) {
+				u = userDao.getContact(user.getAddress().getEmail()
+						, user.getFirstname()
+						, user.getLastname()
+						, user.getLanguageId()
+						, user.getTimeZoneId()
+						, owner);
+			}
 			if (u == null) {
 				u = user.get(userDao);
 				u.setType(User.Type.contact);
@@ -85,8 +95,7 @@ public class MeetingMemberDTO implements
 
 	public static MeetingMemberDTO get(JSONObject o) {
 		MeetingMemberDTO m = new MeetingMemberDTO();
-		long id = o.optLong("id");
-		m.id = id == 0 ? null : id;
+		m.id = optLong(o, "id");
 		m.user = UserDTO.get(o.optJSONObject("user"));
 		return m;
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java Tue Jan 24 17:38:20 2017
@@ -19,6 +19,9 @@
 package org.apache.openmeetings.db.dto.room;
 
 import static org.apache.openmeetings.db.dto.room.RoomOptionsDTO.optInt;
+import static org.apache.openmeetings.db.util.DtoHelper.optEnum;
+import static org.apache.openmeetings.db.util.DtoHelper.optEnumList;
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -287,11 +290,10 @@ public class RoomDTO implements Serializ
 			return null;
 		}
 		RoomDTO r = new RoomDTO();
-		long id = o.optLong("id");
-		r.id = id == 0 ? null : id;
+		r.id = optLong(o, "id");
 		r.name = o.optString("name");
 		r.comment = o.optString("comment");
-		r.type = Room.Type.valueOf(o.getString("type"));
+		r.type = optEnum(Room.Type.class, o, "type");
 		r.numberOfPartizipants = o.optLong("numberOfPartizipants", 4);
 		r.appointment = o.optBoolean("appointment", false);
 		r.confno = o.optString("confno");
@@ -307,13 +309,7 @@ public class RoomDTO implements Serializ
 		r.allowRecording = o.optBoolean("allowRecording", false);
 		r.waitForRecording = o.optBoolean("waitForRecording", false);
 		r.audioOnly = o.optBoolean("audioOnly", false);
-		r.setHiddenElements(new HashSet<RoomElement>());
-		JSONArray hidden = o.optJSONArray("hiddenElements");
-		if (hidden != null) {
-			for (int i = 0; i < hidden.length(); ++i) {
-				r.getHiddenElements().add(RoomElement.valueOf(hidden.getString(i)));
-			}
-		}
+		r.getHiddenElements().addAll(optEnumList(RoomElement.class, o.optJSONArray("hiddenElements")));
 		return r;
 	}
 

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomOptionsDTO.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.db.dto.room;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
+
 import java.io.Serializable;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -90,11 +92,7 @@ public class RoomOptionsDTO implements S
 	public static Integer optInt(JSONObject o, String key) {
 		return o.has(key) && !o.isNull(key) ? o.getInt(key) : null;
 	}
-	
-	public static Long optLong(JSONObject o, String key) {
-		return o.has(key) && !o.isNull(key) ? o.getLong(key) : null;
-	}
-	
+
 	public static RoomOptionsDTO fromString(String s) {
 		JSONObject o = new JSONObject(s);
 		RoomOptionsDTO ro = new RoomOptionsDTO();
@@ -106,7 +104,7 @@ public class RoomOptionsDTO implements S
 		ro.showAudioVideoTest = o.optBoolean("showAudioVideoTest", false);
 		return ro;
 	}
-	
+
 	@Override
 	public String toString() {
 		return new JSONObject(this).toString();

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/user/UserDTO.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,10 @@
  */
 package org.apache.openmeetings.db.dto.user;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optEnum;
+import static org.apache.openmeetings.db.util.DtoHelper.optEnumList;
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
+
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -191,30 +195,23 @@ public class UserDTO implements Serializ
 			return null;
 		}
 		UserDTO u = new UserDTO();
-		long id = o.optLong("id");
-		u.id = id == 0 ? null : id;
+		u.id = optLong(o, "id");
 		u.login = o.optString("login");
 		u.password = o.optString("password");
 		u.firstname = o.optString("firstname");
 		u.lastname = o.optString("lastname");
-		JSONArray rr = o.optJSONArray("rights");
-		if (rr !=  null) {
-			for (int i = 0; i < rr.length(); ++i) {
-				u.rights.add(Right.valueOf(rr.getString(i)));
-			}
-		}
+		u.rights.addAll(optEnumList(Right.class, o.optJSONArray("rights")));
 		u.languageId = o.optLong("languageId");
 		JSONObject a = o.optJSONObject("address");
 		if (a != null) {
-			u.address.setId(a.optLong("id"));
+			u.address.setId(optLong(a, "id"));
 			u.address.setCountry(a.optString("country"));
 			u.address.setEmail(a.optString("email"));
 		}
 		u.timeZoneId = o.optString("timeZoneId");
 		u.externalId = o.optString("externalId");
 		u.externalType = o.optString("externalType");
-		String t = o.optString("type", null);
-		u.type = t == null ? null : Type.valueOf(t);
+		u.type = optEnum(Type.class, o, "type");
 		return u;
 	}
 

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/Address.java Tue Jan 24 17:38:20 2017
@@ -36,56 +36,55 @@ import org.simpleframework.xml.Root;
 @Table(name = "address")
 @Root(name="address")
 public class Address implements IDataProviderEntity {
-
 	private static final long serialVersionUID = 1L;
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	@Column(name = "id")
 	private Long id;
-	
+
 	@Column(name = "additionalname")
 	@Element(data=true, required=false)
 	private String additionalname;
-	
+
 	@Lob
 	@Column(name = "comment", length=2048)
 	@Element(data=true, required=false)
 	private String comment;
-	
+
 	@Column(name = "fax")
 	@Element(data=true, required=false)
 	private String fax;
-	
+
 	@Column(name = "inserted")
 	@Element(name = "starttime",data=true, required=false)
 	private Date inserted;
-	
+
 	@Column(name = "country")
 	@Element(name="country", data=true, required=false)
 	private String country;
-	
+
 	@Column(name = "street")
 	@Element(data=true, required=false)
 	private String street;
-	
+
 	@Column(name = "town")
 	@Element(data=true, required=false)
 	private String town;
-	
+
 	@Column(name = "updated")
 	private Date updated;
-	
+
 	@Column(name = "zip")
 	@Element(data=true, required=false)
 	private String zip;
-	
+
 	@Column(name = "deleted", nullable = false)
 	private boolean deleted;
 
 	@Column(name = "email")
 	@Element(name="mail", data=true, required=false)
 	private String email;
-	
+
 	@Column(name = "phone")
 	@Element(data=true, required=false)
 	private String phone;

Added: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java?rev=1780097&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/DtoHelper.java Tue Jan 24 17:38:20 2017
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.db.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.wicket.ajax.json.JSONArray;
+import org.apache.wicket.ajax.json.JSONObject;
+
+public class DtoHelper {
+	public static Long optLong(JSONObject o, String key) {
+		return o.has(key) && !o.isNull(key) ? o.getLong(key) : null;
+	}
+
+	public static <T extends Enum<T>> T optEnum(Class<T> clazz, JSONObject o, String key) {
+		return o.has(key) && !o.isNull(key) ? Enum.valueOf(clazz, o.getString(key)) : null;
+	}
+
+	public static <T extends Enum<T>> Collection<T> optEnumList(Class<T> clazz, JSONArray arr) {
+		Collection<T> l = new ArrayList<>();
+		if (arr !=  null) {
+			for (int i = 0; i < arr.length(); ++i) {
+				l.add(Enum.valueOf(clazz, arr.getString(i)));
+			}
+		}
+		return l;
+	}
+}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Tue Jan 24 17:38:20 2017
@@ -486,19 +486,23 @@ public class Application extends Authent
 		Room r = i.getRoom();
 		User u = i.getInvitee();
 		if (r != null) {
-			boolean allowed = u.getType() != Type.contact;
-			if (allowed) {
-				allowed = getBean(MainService.class).isRoomAllowedToUser(r, u);
-			}
-			if (!allowed) {
-				PageParameters pp = new PageParameters();
-				pp.add(INVITATION_HASH, i.getHash());
-				if (u.getLanguageId() > 0) {
-					pp.add("language", u.getLanguageId());
-				}
-				link = urlForPage(HashPage.class, pp);
-			} else {
+			if (r.isAppointment() && i.getInvitedBy().getId().equals(u.getId())) {
 				link = getRoomUrlFragment(r.getId()).getLink();
+			} else {
+				boolean allowed = u.getType() != Type.contact;
+				if (allowed) {
+					allowed = getBean(MainService.class).isRoomAllowedToUser(r, u);
+				}
+				if (allowed) {
+					link = getRoomUrlFragment(r.getId()).getLink();
+				} else {
+					PageParameters pp = new PageParameters();
+					pp.add(INVITATION_HASH, i.getHash());
+					if (u.getLanguageId() > 0) {
+						pp.add("language", u.getLanguageId());
+					}
+					link = urlForPage(HashPage.class, pp);
+				}
 			}
 		}
 		Recording rec = i.getRecording();

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java Tue Jan 24 17:38:20 2017
@@ -87,7 +87,7 @@ public abstract class InvitationForm ext
 		add(subject, message);
 		recipients.setLabel(Model.of(Application.getString(216))).setRequired(true).add(new AjaxFormComponentUpdatingBehavior("change") {
 			private static final long serialVersionUID = 1L;
-			
+
 			@Override
 			protected void onUpdate(AjaxRequestTarget target) {
 				url.setModelObject(null);
@@ -154,11 +154,11 @@ public abstract class InvitationForm ext
 		i.setId(null);
 		i.setUpdated(null);
 		i.setUsed(false);
-		
+
 		i.setPassword(CryptProvider.get().hash(i.getPassword()));
 		i.setValidFrom(getDate(from.getModelObject().minusMinutes(5), timeZoneId.getModelObject()));
 		i.setValidTo(getDate(to.getModelObject(), timeZoneId.getModelObject()));
-		
+
 		i.setInvitee(u);
 		i.setHash(UUID.randomUUID().toString());
 		if (Type.contact == u.getType()) {
@@ -232,4 +232,4 @@ public abstract class InvitationForm ext
 			dialog.onSuperClick(target, button);
 		}
 	}
-}
\ No newline at end of file
+}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/AbstractJUnitDefaults.java Tue Jan 24 17:38:20 2017
@@ -48,7 +48,7 @@ public abstract class AbstractJUnitDefau
 	private static final String orgname = "smoketest";
 	private static final String timeZone = "Europe/Berlin";
 	private static final String useremail = "junit@openmeetings.apache.org";
-	
+
 	@Autowired
 	private AppointmentDao appointmentDao;
 	@Autowired
@@ -114,7 +114,7 @@ public abstract class AbstractJUnitDefau
 		if (ap.getReminder() == null) {
 			ap.setReminder(Appointment.Reminder.none);
 		}
-		
+
 		if (r == null) {
 			r = new Room();
 			r.setType(Room.Type.conference);
@@ -178,12 +178,15 @@ public abstract class AbstractJUnitDefau
 		importInitvalues.loadAll(cfg, false);
 	}
 
+	public User getContact(String uuid, Long ownerId) {
+		return userDao.getContact("email" + uuid, "firstname" + uuid, "lastname" + uuid, ownerId);
+	}
+
 	public User createUserContact(Long ownerId) {
-		return createUserContact(UUID.randomUUID().toString(), ownerId);
+		return createUserContact(getContact(UUID.randomUUID().toString(), ownerId), ownerId);
 	}
 
-	public User createUserContact(String uuid, Long ownerId) {
-		User user = userDao.getContact("email" + uuid, "firstname" + uuid, "lastname" + uuid, ownerId);
+	public User createUserContact(User user, Long ownerId) {
 		user = userDao.update(user, ownerId);
 		assertNotNull("Cann't add user", user);
 		return user;

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java Tue Jan 24 17:38:20 2017
@@ -19,14 +19,28 @@
 package org.apache.openmeetings.test.calendar;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
 
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
+import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
+import org.apache.openmeetings.db.entity.calendar.MeetingMember;
+import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.service.calendar.AppointmentLogic;
 import org.apache.openmeetings.test.AbstractWicketTester;
+import org.apache.openmeetings.web.app.WebSession;
+import org.apache.wicket.util.string.StringValue;
 import org.junit.Test;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -39,11 +53,17 @@ public class TestAppointmentAddAppointme
 	private AppointmentLogic appointmentLogic;
 	@Autowired
 	private AppointmentDao appointmentDao;
+	@Autowired
+	private UserDao userDao;
+
+	private void setTime(Appointment a) {
+		a.setStart(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));
+		a.setEnd(Date.from(LocalDateTime.now().plusHours(1).atZone(ZoneId.systemDefault()).toInstant()));
+	}
 
 	@Test
 	public void saveAppointment() throws Exception {
-		log.debug("- 1 MeetingReminderJob.execute");
-		log.warn("- 2 MeetingReminderJob.execute");
+		log.debug("- saveAppointment");
 
 		Calendar start = Calendar.getInstance();
 		start.setTimeInMillis(start.getTimeInMillis() + 600000);
@@ -74,14 +94,45 @@ public class TestAppointmentAddAppointme
 				isMonthly, isYearly, remind, mmClient,
 				roomType, languageId, false, "", -1, userId);
 		a = appointmentDao.update(a, userId);
-		
+
 		Thread.sleep(3000);
-		
+
 		appointmentLogic.doScheduledMeetingReminder();
-		
+
 		Thread.sleep(3000);
-		
-		assertTrue("Saved appointment should have valid id: " + a.getId(), a.getId() != null && a.getId() > 0);
+
+		assertNotNull("Saved appointment should have valid id: " + a.getId(), a.getId());
+	}
+
+	@Test
+	public void testCreate() {
+		Appointment a = new Appointment();
+		a.setTitle("Test title");
+		setTime(a);
+		a.setReminder(Reminder.ical);
+		a.setMeetingMembers(new ArrayList<>());
+		User owner = userDao.get(1L);
+		a.setOwner(owner);
+		a.setRoom(new Room());
+		a.getRoom().setAppointment(true);
+		a.getRoom().setType(Room.Type.conference);
+		for (int i = 0; i < 3; ++i) {
+			MeetingMember mm = new MeetingMember();
+			mm.setUser(getContact(UUID.randomUUID().toString(), owner.getId()));
+			a.getMeetingMembers().add(mm);
+		}
+		a = appointmentDao.update(a, owner.getId());
+		assertNotNull("Saved appointment should have valid id: " + a.getId(), a.getId());
+		assertEquals("Saved appointment should have corect count of guests: ", 3, a.getMeetingMembers().size());
+		for (MeetingMember mm : a.getMeetingMembers()) {
+			assertNotNull("Saved guest should have valid id: ", mm.getId());
+			assertNotNull("Saved guest should have valid invitation: ", mm.getInvitation());
+		}
+
+		WebSession ws = WebSession.get();
+		Appointment a1 = appointmentDao.get(a.getId());
+		ws.checkHashes(StringValue.valueOf(""), StringValue.valueOf(a1.getMeetingMembers().get(0).getInvitation().getHash()));
+		assertTrue("Login via secure hash should be successful", ws.isSignedIn());
 	}
 
 	private static String createClientObj(String firstname, String lastname, String email, String jNameTimeZone) {
@@ -94,5 +145,4 @@ public class TestAppointmentAddAppointme
 			.append(jNameTimeZone);
 		return sb.toString();
 	}
-
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java Tue Jan 24 17:38:20 2017
@@ -32,6 +32,7 @@ import org.apache.openmeetings.db.dao.ro
 import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dto.basic.ServiceResult;
 import org.apache.openmeetings.db.dto.calendar.AppointmentDTO;
+import org.apache.openmeetings.db.dto.calendar.MeetingMemberDTO;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.GroupUser;
@@ -174,14 +175,14 @@ public class TestCalendarService extends
 		JSONObject o = createAppointment()
 				.put("meetingMembers", new JSONArray()
 						.put(new JSONObject().put("user", new JSONObject()
-								.put("firstname", "Jhon 1")
+								.put("firstname", "John 1")
 								.put("lastname", "Doe")
-								.put("Address", new JSONObject().put("email", "jhon1@doe.email"))
+								.put("address", new JSONObject().put("email", "jhon1@doe.email"))
 								))
 						.put(new JSONObject().put("user", new JSONObject()
-								.put("firstname", "Jhon 2")
+								.put("firstname", "John 2")
 								.put("lastname", "Doe")
-								.put("Address", new JSONObject().put("email", "jhon2@doe.email"))
+								.put("address", new JSONObject().put("email", "jhon2@doe.email"))
 								))
 						);
 
@@ -202,6 +203,9 @@ public class TestCalendarService extends
 		assertNotNull("Valid DTO should be returned", dto);
 		assertNotNull("DTO id should be valid", dto.getId());
 		assertEquals("DTO should have 2 attendees", 2, dto.getMeetingMembers().size());
+		for (MeetingMemberDTO mm : dto.getMeetingMembers()) {
+			assertNotNull("Email should be valid", mm.getUser().getAddress().getEmail());
+		}
 
 		//try to change MM list
 		JSONObject o1 = AppointmentParamConverter.json(dto)

Modified: openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/CalendarWebService.java Tue Jan 24 17:38:20 2017
@@ -303,10 +303,7 @@ public class CalendarWebService {
 				throw new ServiceException("Insufficient permissions"); //TODO code -26
 			}
 			if (AuthLevelUtil.hasUserLevel(u.getRights())) {
-				Appointment a = appointment.get(userDao, appointmentDao);
-				if (a.getOwner() == null) {
-					a.setOwner(u);
-				}
+				Appointment a = appointment.get(userDao, appointmentDao, u);
 				if (a.getRoom().getId() != null) {
 					if (a.getRoom().isAppointment()) {
 						a.getRoom().setIspublic(false);

Modified: openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.webservice.util;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optEnum;
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
 import static org.apache.openmeetings.util.CalendarPatterns.ISO8601_FULL_FORMAT;
 
 import java.util.Date;
@@ -37,8 +39,7 @@ public class AppointmentParamConverter i
 	public AppointmentDTO fromString(String val) {
 		JSONObject o = new JSONObject(val);
 		AppointmentDTO a = new AppointmentDTO();
-		long id = o.optLong("id");
-		a.setId(id == 0 ? null : id);
+		a.setId(optLong(o, "id"));
 		a.setTitle(o.optString("title"));
 		a.setLocation(o.optString("location"));
 		a.setOwner(UserDTO.get(o.optJSONObject("owner")));
@@ -49,8 +50,7 @@ public class AppointmentParamConverter i
 		a.setInserted(DateParamConverter.get(o.optString("inserted")));
 		a.setUpdated(DateParamConverter.get(o.optString("updated")));
 		a.setDeleted(o.optBoolean("inserted"));
-		String r = o.optString("reminder", null);
-		a.setReminder(r == null ? null : Reminder.valueOf(r));
+		a.setReminder(optEnum(Reminder.class, o, "reminder"));
 		a.setRoom(RoomDTO.get(o.optJSONObject("room")));
 		a.setIcalId(o.optString("icalId"));
 		JSONArray mm = o.optJSONArray("meetingMembers");

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java Tue Jan 24 17:38:20 2017
@@ -69,9 +69,7 @@ public class AppointmentDao {
 	/*
 	 * insert, update, delete, select
 	 */
-
 	// -----------------------------------------------------------------------------------------------
-
 	public Appointment get(Long id) {
 		TypedQuery<Appointment> query = em.createNamedQuery("getAppointmentById", Appointment.class);
 		query.setParameter("id", id);
@@ -94,7 +92,6 @@ public class AppointmentDao {
 		} catch (NoResultException ex) {
 			//no-op
 		}
-
 		return a;
 	}
 
@@ -153,7 +150,7 @@ public class AppointmentDao {
 			em.persist(a);
 		} else {
 			a.setUpdated(new Date());
-			a =	em.merge(a);
+			a = em.merge(a);
 		}
 		return a;
 	}

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/AppointmentDTO.java Tue Jan 24 17:38:20 2017
@@ -36,6 +36,7 @@ import org.apache.openmeetings.db.dto.us
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.wicket.ajax.json.JSONObject;
 
 @XmlRootElement
@@ -92,7 +93,7 @@ public class AppointmentDTO implements S
 		reminderEmailSend = a.isReminderEmailSend();
 	}
 
-	public Appointment get(UserDao userDao, AppointmentDao appointmentDao) {
+	public Appointment get(UserDao userDao, AppointmentDao appointmentDao, User u) {
 		Appointment a = id == null ? new Appointment() : appointmentDao.get(id);
 		a.setId(id);
 		a.setTitle(title);
@@ -100,7 +101,7 @@ public class AppointmentDTO implements S
 		a.setStart(start.getTime());
 		a.setEnd(end.getTime());
 		a.setDescription(description);
-		a.setOwner(owner == null ? null : userDao.get(owner.getId()));
+		a.setOwner(owner == null ? u : userDao.get(owner.getId()));
 		a.setInserted(inserted);
 		a.setUpdated(updated);
 		a.setDeleted(deleted);
@@ -109,7 +110,7 @@ public class AppointmentDTO implements S
 		a.setIcalId(icalId);
 		a.setMeetingMembers(new ArrayList<MeetingMember>());
 		for(MeetingMemberDTO mm : meetingMembers) {
-			MeetingMember m = mm.get(userDao);
+			MeetingMember m = mm.get(userDao, u);
 			m.setAppointment(a);
 			a.getMeetingMembers().add(m);
 		}

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/calendar/MeetingMemberDTO.java Tue Jan 24 17:38:20 2017
@@ -18,6 +18,8 @@
  */
 package org.apache.openmeetings.db.dto.calendar;
 
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
+
 import java.io.Serializable;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -44,7 +46,7 @@ public class MeetingMemberDTO implements
 		this.user = new UserDTO(mm.getUser());
 	}
 
-	public MeetingMember get(UserDao userDao) {
+	public MeetingMember get(UserDao userDao, User owner) {
 		MeetingMember mm = new MeetingMember();
 		mm.setId(id);
 		if (user.getId() != null) {
@@ -55,6 +57,14 @@ public class MeetingMemberDTO implements
 				// try to get ext. user
 				u = userDao.getExternalUser(user.getExternalId(), user.getExternalType());
 			}
+			if (u == null && user.getAddress() != null) {
+				u = userDao.getContact(user.getAddress().getEmail()
+						, user.getFirstname()
+						, user.getLastname()
+						, user.getLanguageId()
+						, user.getTimeZoneId()
+						, owner);
+			}
 			if (u == null) {
 				u = user.get(userDao);
 				u.setType(User.Type.contact);
@@ -85,8 +95,7 @@ public class MeetingMemberDTO implements
 
 	public static MeetingMemberDTO get(JSONObject o) {
 		MeetingMemberDTO m = new MeetingMemberDTO();
-		long id = o.optLong("id");
-		m.id = id == 0 ? null : id;
+		m.id = optLong(o, "id");
 		m.user = UserDTO.get(o.optJSONObject("user"));
 		return m;
 	}

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java?rev=1780097&r1=1780096&r2=1780097&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dto/room/RoomDTO.java Tue Jan 24 17:38:20 2017
@@ -19,6 +19,9 @@
 package org.apache.openmeetings.db.dto.room;
 
 import static org.apache.openmeetings.db.dto.room.RoomOptionsDTO.optInt;
+import static org.apache.openmeetings.db.util.DtoHelper.optEnum;
+import static org.apache.openmeetings.db.util.DtoHelper.optEnumList;
+import static org.apache.openmeetings.db.util.DtoHelper.optLong;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -287,11 +290,10 @@ public class RoomDTO implements Serializ
 			return null;
 		}
 		RoomDTO r = new RoomDTO();
-		long id = o.optLong("id");
-		r.id = id == 0 ? null : id;
+		r.id = optLong(o, "id");
 		r.name = o.optString("name");
 		r.comment = o.optString("comment");
-		r.type = Room.Type.valueOf(o.getString("type"));
+		r.type = optEnum(Room.Type.class, o, "type");
 		r.numberOfPartizipants = o.optLong("numberOfPartizipants", 4);
 		r.appointment = o.optBoolean("appointment", false);
 		r.confno = o.optString("confno");
@@ -307,13 +309,7 @@ public class RoomDTO implements Serializ
 		r.allowRecording = o.optBoolean("allowRecording", false);
 		r.waitForRecording = o.optBoolean("waitForRecording", false);
 		r.audioOnly = o.optBoolean("audioOnly", false);
-		r.setHiddenElements(new HashSet<RoomElement>());
-		JSONArray hidden = o.optJSONArray("hiddenElements");
-		if (hidden != null) {
-			for (int i = 0; i < hidden.length(); ++i) {
-				r.getHiddenElements().add(RoomElement.valueOf(hidden.getString(i)));
-			}
-		}
+		r.getHiddenElements().addAll(optEnumList(RoomElement.class, o.optJSONArray("hiddenElements")));
 		return r;
 	}