Author: solomax
Date: Wed Jan 25 12:02:26 2017
New Revision: 1780175

URL: http://svn.apache.org/viewvc?rev=1780175&view=rev
Log:
[OPENMEETINGS-1541] more calendar hash fixes; user is not deleted on 
MM/invitation deletion

Modified:
    
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.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/entity/calendar/MeetingMember.java
    
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.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/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/util/AppointmentParamConverter.java
    
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.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/entity/calendar/MeetingMember.java
    
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.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/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/util/AppointmentParamConverter.java
    
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.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/entity/calendar/MeetingMember.java
    
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
    
openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.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/util/AppointmentParamConverter.java

Modified: 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
 (original)
+++ 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
 Wed Jan 25 12:02:26 2017
@@ -40,10 +40,10 @@ import org.threeten.bp.ZonedDateTime;
 @Transactional
 public class InvitationDao {
        private static final Logger log = 
Red5LoggerFactory.getLogger(InvitationDao.class, webAppRootKey);
-       
+
        @PersistenceContext
        private EntityManager em;
-       
+
        public Invitation update(Invitation invitation) {
                if (invitation.getId() == null) {
                        invitation.setInserted(new Date());
@@ -54,24 +54,21 @@ public class InvitationDao {
                }
                return invitation;
        }
-       
+
        public Invitation get(Long invId) {
                try {
-                       
                        TypedQuery<Invitation> query = 
em.createNamedQuery("getInvitationbyId", Invitation.class);
                        query.setParameter("id", invId);
-                       
                        try {
                                return query.getSingleResult();
                        } catch (NoResultException ex) {
                        }
-
                } catch (Exception e) {
                        log.error("get : ", e);
                }
                return null;
        }
-       
+
        public Invitation getByHash(String hash, boolean hidePass, boolean 
markUsed) {
                List<Invitation> list = 
em.createNamedQuery("getInvitationByHashCode", Invitation.class)
                                .setParameter("hashCode", hash).getResultList();

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -100,8 +100,15 @@ public class MeetingMemberDTO implements
                return m;
        }
 
+       public static JSONObject json(MeetingMemberDTO mm) {
+               JSONObject m = new JSONObject();
+               m.put("id", mm.getId());
+               m.put("user", UserDTO.json(mm.getUser()));
+               return m;
+       }
+
        @Override
        public String toString() {
-               return new JSONObject(this).toString();
+               return json(this).toString();
        }
 }

Modified: 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
 (original)
+++ 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
 Wed Jan 25 12:02:26 2017
@@ -59,7 +59,7 @@ public class MeetingMember implements ID
        @Element(name = "meetingMemberId", data = true)
        private Long id;
 
-       @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+       @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, 
CascadeType.PERSIST})
        @JoinColumn(name = "user_id", nullable = true)
        @ForeignKey(enabled = true)
        @Element(name = "userid", data = true, required = false)

Modified: 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
 (original)
+++ 
openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
 Wed Jan 25 12:02:26 2017
@@ -57,17 +57,17 @@ public class Invitation implements IData
                , Update
                , Cancel
        }
-       
+
        public enum Valid {
                OneTime
                , Period
                , Endless;
-               
+
                public static Valid fromInt(int valid) {
                        return valid == 1 ? Endless : (valid == 2 ? Period : 
OneTime);
                }
        }
-       
+
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
@@ -77,13 +77,13 @@ public class Invitation implements IData
        @JoinColumn(name = "invited_by", nullable = true)
        @ForeignKey(enabled = true)
        private User invitedBy;
-       
+
        @Column(name = "inserted")
        private Date inserted;
-       
+
        @Column(name = "updated")
        private Date updated;
-       
+
        @Column(name = "deleted", nullable = false)
        private boolean deleted;
 
@@ -101,7 +101,7 @@ public class Invitation implements IData
        @Column(name = "hash")
        private String hash;
 
-       @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+       @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, 
CascadeType.PERSIST})
        @JoinColumn(name = "invitee_id", nullable = true)
        @ForeignKey(enabled = true)
        private User invitee;
@@ -117,16 +117,16 @@ public class Invitation implements IData
        @Column(name = "valid")
        @Enumerated(EnumType.STRING)
        private Valid valid = Valid.Period;
-       
+
        @Column(name = "valid_from")
        private Date validFrom;
-       
+
        @Column(name = "valid_to")
        private Date validTo;
-       
+
        @Column(name = "was_used", nullable = false)
        private boolean used;
-       
+
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "appointment_id", nullable = true)
        @ForeignKey(enabled = true)
@@ -135,9 +135,9 @@ public class Invitation implements IData
        //variable used in Flash
        @Transient
        private boolean allowEntry = true;
-       
+
        public Invitation() {}
-       
+
        public Invitation(Invitation i) {
                id = i.id;
                invitedBy = i.invitedBy;
@@ -156,7 +156,7 @@ public class Invitation implements IData
                used = i.used;
                appointment = i.appointment;
        }
-       
+
        @Override
        public Long getId() {
                return id;
@@ -286,7 +286,7 @@ public class Invitation implements IData
        public void setValid(Valid valid) {
                this.valid = valid;
        }
-       
+
        public boolean isAllowEntry() {
                return allowEntry;
        }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -440,7 +440,7 @@ public class Application extends Authent
                        if (r.isAppointment() && 
i.getInvitedBy().getId().equals(u.getId())) {
                                link = getRoomUrlFragment(r.getId()).getLink();
                        } else {
-                               boolean allowed = u.getType() != Type.contact;
+                               boolean allowed = Type.contact != u.getType() 
&& Type.external != u.getType();
                                if (allowed) {
                                        allowed = 
getBean(MainService.class).isRoomAllowedToUser(r, u);
                                }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -56,7 +56,7 @@ public class TestAppointmentAddAppointme
        @Autowired
        private UserDao userDao;
 
-       private void setTime(Appointment a) {
+       private static 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()));
        }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -19,21 +19,29 @@
 package org.apache.openmeetings.test.webservice;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.UUID;
 
 import javax.ws.rs.core.Form;
 import javax.ws.rs.core.Response;
 
+import org.apache.openmeetings.db.dao.calendar.MeetingMemberDao;
+import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
 import org.apache.openmeetings.db.dao.user.GroupDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
 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.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
@@ -49,6 +57,12 @@ public class TestCalendarService extends
        private GroupDao groupDao;
        @Autowired
        private RoomDao roomDao;
+       @Autowired
+       private MeetingMemberDao mmDao;
+       @Autowired
+       private InvitationDao invitationDao;
+       @Autowired
+       private UserDao userDao;
 
        private void actualTest(Room r) throws Exception {
                String uuid = UUID.randomUUID().toString();
@@ -78,10 +92,10 @@ public class TestCalendarService extends
        private static JSONObject createAppointment() {
                return new JSONObject()
                        .put("title", "test")
-                       .put("start", "2017-01-20T20:30:03+0300")
-                       .put("end", "2017-01-20T21:30:03+0300")
+                       .put("start", "2025-01-20T20:30:03+0300")
+                       .put("end", "2025-01-20T21:30:03+0300")
                        .put("description", "Русский Тест")
-                       .put("reminder", "none")
+                       .put("reminder", "email")
                        .put("room", new JSONObject()
                                        .put("name", "test24")
                                        .put("comment", "appointment test room")
@@ -112,19 +126,24 @@ public class TestCalendarService extends
                        .put("reminderEmailSend", false);
        }
 
-       @Test
-       public void testCreate() throws Exception {
-               JSONObject o = createAppointment();
-
+       private String loginNewUser() throws Exception {
                String uuid = UUID.randomUUID().toString();
                User u = getUser(uuid);
                u.getGroupUsers().add(new GroupUser(groupDao.get(1L), u));
                u = createUser(u);
                ServiceResult sr = login(u.getLogin(), getRandomPass(uuid));
+               return sr.getMessage();
+       }
+
+       @Test
+       public void testCreate() throws Exception {
+               JSONObject o = createAppointment();
+
+               String sid = loginNewUser();
 
                Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -170,31 +189,24 @@ public class TestCalendarService extends
                assertNotNull("DTO id should be valid", dto.getId());
        }
 
-       @Test
-       public void testCreateWithMm() throws Exception {
+       private static AppointmentDTO createEventWithGuests(String sid) throws 
Exception {
                JSONObject o = createAppointment()
                                .put("meetingMembers", new JSONArray()
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                
.put("firstname", "John 1")
                                                                
.put("lastname", "Doe")
-                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
+                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
                                                                ))
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                
.put("firstname", "John 2")
                                                                
.put("lastname", "Doe")
-                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
+                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
                                                                ))
                                                );
 
-               String uuid = UUID.randomUUID().toString();
-               User u = getUser(uuid);
-               u.getGroupUsers().add(new GroupUser(groupDao.get(1L), u));
-               u = createUser(u);
-               ServiceResult sr = login(u.getLogin(), getRandomPass(uuid));
-
                Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -207,15 +219,23 @@ public class TestCalendarService extends
                        assertNotNull("Email should be valid", 
mm.getUser().getAddress().getEmail());
                }
 
+               return dto;
+       }
+
+       @Test
+       public void testCreateWithGuests() throws Exception {
+               String sid = loginNewUser();
+               AppointmentDTO dto = createEventWithGuests(sid);
+
                //try to change MM list
                JSONObject o1 = AppointmentParamConverter.json(dto)
                                .put("meetingMembers", new JSONArray()
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                .put("id", 
1))));
 
-               resp = getClient(CALENDAR_SERVICE_URL)
+               Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o1.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -225,4 +245,35 @@ public class TestCalendarService extends
                assertNotNull("DTO id should be valid", dto.getId());
                assertEquals("DTO should have 1 attendees", 1, 
dto.getMeetingMembers().size());
        }
+
+       @Test
+       public void testCreateWithGuestsCleanOne() throws Exception {
+               String sid = loginNewUser();
+               AppointmentDTO dto = createEventWithGuests(sid);
+               List<MeetingMemberDTO> initialList = new 
ArrayList<>(dto.getMeetingMembers());
+               MeetingMember mm = mmDao.get(initialList.get(initialList.size() 
- 1).getId());
+               Long mmId = mm.getId(), mmUserId = mm.getUser().getId();
+               String hash = mm.getInvitation().getHash();
+               dto.getMeetingMembers().remove(initialList.size() - 1);
+
+               //try to change MM list
+               JSONObject o = AppointmentParamConverter.json(dto);
+               Response resp = getClient(CALENDAR_SERVICE_URL)
+                               .path("/")
+                               .query("sid", sid)
+                               .form(new Form().param("appointment", 
o.toString()));
+
+               assertNotNull("Valid AppointmentDTO should be returned", resp);
+               assertEquals("Call should be successful", 
Response.Status.OK.getStatusCode(), resp.getStatus());
+               dto = resp.readEntity(AppointmentDTO.class);
+               assertNotNull("Valid DTO should be returned", dto);
+               assertNotNull("DTO id should be valid", dto.getId());
+               assertEquals("DTO should have 1 attendees", 1, 
dto.getMeetingMembers().size());
+
+               assertNull("Meeting member should deleted", mmDao.get(mmId));
+               assertNull("Invitation should deleted", 
invitationDao.getByHash(hash, true, false));
+               User uc = userDao.get(mmUserId);
+               assertNotNull("Meeting member user should not be deleted", uc);
+               assertFalse("Meeting member user should not be deleted", 
uc.isDeleted());
+       }
 }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -69,7 +69,7 @@ public class AppointmentParamConverter i
 
        public static JSONObject json(AppointmentDTO val) {
                Date i = val.getInserted(), u = val.getUpdated();
-               return new JSONObject(val)
+               JSONObject o = new JSONObject(val)
                                .put("owner", UserDTO.json(val.getOwner()))
                                .put("room", RoomDTO.json(val.getRoom()))
                                .put("reminder", val.getReminder() == null ? 
null : val.getReminder().name())
@@ -77,6 +77,14 @@ public class AppointmentParamConverter i
                                .put("end", 
ISO8601_FULL_FORMAT.format(val.getEnd()))
                                .put("inserted", i == null ? null : 
ISO8601_FULL_FORMAT.format(i))
                                .put("updated", u == null ? null : 
ISO8601_FULL_FORMAT.format(u));
+               if (val.getMeetingMembers() != null) {
+                       JSONArray rr = new JSONArray();
+                       for(MeetingMemberDTO mm : val.getMeetingMembers()) {
+                               rr.put(MeetingMemberDTO.json(mm));
+                       }
+                       o.put("meetingMembers", rr);
+               }
+               return o;
        }
 
        @Override

Modified: 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
 (original)
+++ 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
 Wed Jan 25 12:02:26 2017
@@ -40,10 +40,10 @@ import org.threeten.bp.ZonedDateTime;
 @Transactional
 public class InvitationDao {
        private static final Logger log = 
Red5LoggerFactory.getLogger(InvitationDao.class, webAppRootKey);
-       
+
        @PersistenceContext
        private EntityManager em;
-       
+
        public Invitation update(Invitation invitation) {
                if (invitation.getId() == null) {
                        invitation.setInserted(new Date());
@@ -54,24 +54,21 @@ public class InvitationDao {
                }
                return invitation;
        }
-       
+
        public Invitation get(Long invId) {
                try {
-                       
                        TypedQuery<Invitation> query = 
em.createNamedQuery("getInvitationbyId", Invitation.class);
                        query.setParameter("id", invId);
-                       
                        try {
                                return query.getSingleResult();
                        } catch (NoResultException ex) {
                        }
-
                } catch (Exception e) {
                        log.error("get : ", e);
                }
                return null;
        }
-       
+
        public Invitation getByHash(String hash, boolean hidePass, boolean 
markUsed) {
                List<Invitation> list = 
em.createNamedQuery("getInvitationByHashCode", Invitation.class)
                                .setParameter("hashCode", hash).getResultList();

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -100,8 +100,15 @@ public class MeetingMemberDTO implements
                return m;
        }
 
+       public static JSONObject json(MeetingMemberDTO mm) {
+               JSONObject m = new JSONObject();
+               m.put("id", mm.getId());
+               m.put("user", UserDTO.json(mm.getUser()));
+               return m;
+       }
+
        @Override
        public String toString() {
-               return new JSONObject(this).toString();
+               return json(this).toString();
        }
 }

Modified: 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
 (original)
+++ 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
 Wed Jan 25 12:02:26 2017
@@ -59,7 +59,7 @@ public class MeetingMember implements ID
        @Element(name = "meetingMemberId", data = true)
        private Long id;
 
-       @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+       @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, 
CascadeType.PERSIST})
        @JoinColumn(name = "user_id", nullable = true)
        @ForeignKey(enabled = true)
        @Element(name = "userid", data = true, required = false)

Modified: 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
 (original)
+++ 
openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
 Wed Jan 25 12:02:26 2017
@@ -57,17 +57,17 @@ public class Invitation implements IData
                , Update
                , Cancel
        }
-       
+
        public enum Valid {
                OneTime
                , Period
                , Endless;
-               
+
                public static Valid fromInt(int valid) {
                        return valid == 1 ? Endless : (valid == 2 ? Period : 
OneTime);
                }
        }
-       
+
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
@@ -77,13 +77,13 @@ public class Invitation implements IData
        @JoinColumn(name = "invited_by", nullable = true)
        @ForeignKey(enabled = true)
        private User invitedBy;
-       
+
        @Column(name = "inserted")
        private Date inserted;
-       
+
        @Column(name = "updated")
        private Date updated;
-       
+
        @Column(name = "deleted", nullable = false)
        private boolean deleted;
 
@@ -101,7 +101,7 @@ public class Invitation implements IData
        @Column(name = "hash")
        private String hash;
 
-       @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+       @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, 
CascadeType.PERSIST})
        @JoinColumn(name = "invitee_id", nullable = true)
        @ForeignKey(enabled = true)
        private User invitee;
@@ -117,16 +117,16 @@ public class Invitation implements IData
        @Column(name = "valid")
        @Enumerated(EnumType.STRING)
        private Valid valid = Valid.Period;
-       
+
        @Column(name = "valid_from")
        private Date validFrom;
-       
+
        @Column(name = "valid_to")
        private Date validTo;
-       
+
        @Column(name = "was_used", nullable = false)
        private boolean used;
-       
+
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "appointment_id", nullable = true)
        @ForeignKey(enabled = true)
@@ -135,9 +135,9 @@ public class Invitation implements IData
        //variable used in Flash
        @Transient
        private boolean allowEntry = true;
-       
+
        public Invitation() {}
-       
+
        public Invitation(Invitation i) {
                id = i.id;
                invitedBy = i.invitedBy;
@@ -156,7 +156,7 @@ public class Invitation implements IData
                used = i.used;
                appointment = i.appointment;
        }
-       
+
        @Override
        public Long getId() {
                return id;
@@ -286,7 +286,7 @@ public class Invitation implements IData
        public void setValid(Valid valid) {
                this.valid = valid;
        }
-       
+
        public boolean isAllowEntry() {
                return allowEntry;
        }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -489,7 +489,7 @@ public class Application extends Authent
                        if (r.isAppointment() && 
i.getInvitedBy().getId().equals(u.getId())) {
                                link = getRoomUrlFragment(r.getId()).getLink();
                        } else {
-                               boolean allowed = u.getType() != Type.contact;
+                               boolean allowed = Type.contact != u.getType() 
&& Type.external != u.getType();
                                if (allowed) {
                                        allowed = 
getBean(MainService.class).isRoomAllowedToUser(r, u);
                                }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -56,7 +56,7 @@ public class TestAppointmentAddAppointme
        @Autowired
        private UserDao userDao;
 
-       private void setTime(Appointment a) {
+       private static 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()));
        }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -19,21 +19,29 @@
 package org.apache.openmeetings.test.webservice;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.UUID;
 
 import javax.ws.rs.core.Form;
 import javax.ws.rs.core.Response;
 
+import org.apache.openmeetings.db.dao.calendar.MeetingMemberDao;
+import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
 import org.apache.openmeetings.db.dao.user.GroupDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
 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.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
@@ -49,6 +57,12 @@ public class TestCalendarService extends
        private GroupDao groupDao;
        @Autowired
        private RoomDao roomDao;
+       @Autowired
+       private MeetingMemberDao mmDao;
+       @Autowired
+       private InvitationDao invitationDao;
+       @Autowired
+       private UserDao userDao;
 
        private void actualTest(Room r) throws Exception {
                String uuid = UUID.randomUUID().toString();
@@ -78,10 +92,10 @@ public class TestCalendarService extends
        private static JSONObject createAppointment() {
                return new JSONObject()
                        .put("title", "test")
-                       .put("start", "2017-01-20T20:30:03+0300")
-                       .put("end", "2017-01-20T21:30:03+0300")
+                       .put("start", "2025-01-20T20:30:03+0300")
+                       .put("end", "2025-01-20T21:30:03+0300")
                        .put("description", "Русский Тест")
-                       .put("reminder", "none")
+                       .put("reminder", "email")
                        .put("room", new JSONObject()
                                        .put("name", "test24")
                                        .put("comment", "appointment test room")
@@ -112,19 +126,24 @@ public class TestCalendarService extends
                        .put("reminderEmailSend", false);
        }
 
-       @Test
-       public void testCreate() throws Exception {
-               JSONObject o = createAppointment();
-
+       private String loginNewUser() throws Exception {
                String uuid = UUID.randomUUID().toString();
                User u = getUser(uuid);
                u.getGroupUsers().add(new GroupUser(groupDao.get(1L), u));
                u = createUser(u);
                ServiceResult sr = login(u.getLogin(), getRandomPass(uuid));
+               return sr.getMessage();
+       }
+
+       @Test
+       public void testCreate() throws Exception {
+               JSONObject o = createAppointment();
+
+               String sid = loginNewUser();
 
                Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -170,31 +189,24 @@ public class TestCalendarService extends
                assertNotNull("DTO id should be valid", dto.getId());
        }
 
-       @Test
-       public void testCreateWithMm() throws Exception {
+       private static AppointmentDTO createEventWithGuests(String sid) throws 
Exception {
                JSONObject o = createAppointment()
                                .put("meetingMembers", new JSONArray()
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                
.put("firstname", "John 1")
                                                                
.put("lastname", "Doe")
-                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
+                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
                                                                ))
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                
.put("firstname", "John 2")
                                                                
.put("lastname", "Doe")
-                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
+                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
                                                                ))
                                                );
 
-               String uuid = UUID.randomUUID().toString();
-               User u = getUser(uuid);
-               u.getGroupUsers().add(new GroupUser(groupDao.get(1L), u));
-               u = createUser(u);
-               ServiceResult sr = login(u.getLogin(), getRandomPass(uuid));
-
                Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -207,15 +219,23 @@ public class TestCalendarService extends
                        assertNotNull("Email should be valid", 
mm.getUser().getAddress().getEmail());
                }
 
+               return dto;
+       }
+
+       @Test
+       public void testCreateWithGuests() throws Exception {
+               String sid = loginNewUser();
+               AppointmentDTO dto = createEventWithGuests(sid);
+
                //try to change MM list
                JSONObject o1 = AppointmentParamConverter.json(dto)
                                .put("meetingMembers", new JSONArray()
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                .put("id", 
1))));
 
-               resp = getClient(CALENDAR_SERVICE_URL)
+               Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o1.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -225,4 +245,35 @@ public class TestCalendarService extends
                assertNotNull("DTO id should be valid", dto.getId());
                assertEquals("DTO should have 1 attendees", 1, 
dto.getMeetingMembers().size());
        }
+
+       @Test
+       public void testCreateWithGuestsCleanOne() throws Exception {
+               String sid = loginNewUser();
+               AppointmentDTO dto = createEventWithGuests(sid);
+               List<MeetingMemberDTO> initialList = new 
ArrayList<>(dto.getMeetingMembers());
+               MeetingMember mm = mmDao.get(initialList.get(initialList.size() 
- 1).getId());
+               Long mmId = mm.getId(), mmUserId = mm.getUser().getId();
+               String hash = mm.getInvitation().getHash();
+               dto.getMeetingMembers().remove(initialList.size() - 1);
+
+               //try to change MM list
+               JSONObject o = AppointmentParamConverter.json(dto);
+               Response resp = getClient(CALENDAR_SERVICE_URL)
+                               .path("/")
+                               .query("sid", sid)
+                               .form(new Form().param("appointment", 
o.toString()));
+
+               assertNotNull("Valid AppointmentDTO should be returned", resp);
+               assertEquals("Call should be successful", 
Response.Status.OK.getStatusCode(), resp.getStatus());
+               dto = resp.readEntity(AppointmentDTO.class);
+               assertNotNull("Valid DTO should be returned", dto);
+               assertNotNull("DTO id should be valid", dto.getId());
+               assertEquals("DTO should have 1 attendees", 1, 
dto.getMeetingMembers().size());
+
+               assertNull("Meeting member should deleted", mmDao.get(mmId));
+               assertNull("Invitation should deleted", 
invitationDao.getByHash(hash, true, false));
+               User uc = userDao.get(mmUserId);
+               assertNotNull("Meeting member user should not be deleted", uc);
+               assertFalse("Meeting member user should not be deleted", 
uc.isDeleted());
+       }
 }

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -69,7 +69,7 @@ public class AppointmentParamConverter i
 
        public static JSONObject json(AppointmentDTO val) {
                Date i = val.getInserted(), u = val.getUpdated();
-               return new JSONObject(val)
+               JSONObject o = new JSONObject(val)
                                .put("owner", UserDTO.json(val.getOwner()))
                                .put("room", RoomDTO.json(val.getRoom()))
                                .put("reminder", val.getReminder() == null ? 
null : val.getReminder().name())
@@ -77,6 +77,14 @@ public class AppointmentParamConverter i
                                .put("end", 
ISO8601_FULL_FORMAT.format(val.getEnd()))
                                .put("inserted", i == null ? null : 
ISO8601_FULL_FORMAT.format(i))
                                .put("updated", u == null ? null : 
ISO8601_FULL_FORMAT.format(u));
+               if (val.getMeetingMembers() != null) {
+                       JSONArray rr = new JSONArray();
+                       for(MeetingMemberDTO mm : val.getMeetingMembers()) {
+                               rr.put(MeetingMemberDTO.json(mm));
+                       }
+                       o.put("meetingMembers", rr);
+               }
+               return o;
        }
 
        @Override

Modified: 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
 (original)
+++ 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
 Wed Jan 25 12:02:26 2017
@@ -40,10 +40,10 @@ import org.threeten.bp.ZonedDateTime;
 @Transactional
 public class InvitationDao {
        private static final Logger log = 
Red5LoggerFactory.getLogger(InvitationDao.class, webAppRootKey);
-       
+
        @PersistenceContext
        private EntityManager em;
-       
+
        public Invitation update(Invitation invitation) {
                if (invitation.getId() == null) {
                        invitation.setInserted(new Date());
@@ -54,24 +54,21 @@ public class InvitationDao {
                }
                return invitation;
        }
-       
+
        public Invitation get(Long invId) {
                try {
-                       
                        TypedQuery<Invitation> query = 
em.createNamedQuery("getInvitationbyId", Invitation.class);
                        query.setParameter("id", invId);
-                       
                        try {
                                return query.getSingleResult();
                        } catch (NoResultException ex) {
                        }
-
                } catch (Exception e) {
                        log.error("get : ", e);
                }
                return null;
        }
-       
+
        public Invitation getByHash(String hash, boolean hidePass, boolean 
markUsed) {
                List<Invitation> list = 
em.createNamedQuery("getInvitationByHashCode", Invitation.class)
                                .setParameter("hashCode", hash).getResultList();

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=1780175&r1=1780174&r2=1780175&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
 Wed Jan 25 12:02:26 2017
@@ -100,8 +100,15 @@ public class MeetingMemberDTO implements
                return m;
        }
 
+       public static JSONObject json(MeetingMemberDTO mm) {
+               JSONObject m = new JSONObject();
+               m.put("id", mm.getId());
+               m.put("user", UserDTO.json(mm.getUser()));
+               return m;
+       }
+
        @Override
        public String toString() {
-               return new JSONObject(this).toString();
+               return json(this).toString();
        }
 }

Modified: 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
 (original)
+++ 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/calendar/MeetingMember.java
 Wed Jan 25 12:02:26 2017
@@ -59,7 +59,7 @@ public class MeetingMember implements ID
        @Element(name = "meetingMemberId", data = true)
        private Long id;
 
-       @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+       @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, 
CascadeType.PERSIST})
        @JoinColumn(name = "user_id", nullable = true)
        @ForeignKey(enabled = true)
        @Element(name = "userid", data = true, required = false)

Modified: 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
 (original)
+++ 
openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
 Wed Jan 25 12:02:26 2017
@@ -57,17 +57,17 @@ public class Invitation implements IData
                , Update
                , Cancel
        }
-       
+
        public enum Valid {
                OneTime
                , Period
                , Endless;
-               
+
                public static Valid fromInt(int valid) {
                        return valid == 1 ? Endless : (valid == 2 ? Period : 
OneTime);
                }
        }
-       
+
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
@@ -77,13 +77,13 @@ public class Invitation implements IData
        @JoinColumn(name = "invited_by", nullable = true)
        @ForeignKey(enabled = true)
        private User invitedBy;
-       
+
        @Column(name = "inserted")
        private Date inserted;
-       
+
        @Column(name = "updated")
        private Date updated;
-       
+
        @Column(name = "deleted", nullable = false)
        private boolean deleted;
 
@@ -101,7 +101,7 @@ public class Invitation implements IData
        @Column(name = "hash")
        private String hash;
 
-       @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+       @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, 
CascadeType.PERSIST})
        @JoinColumn(name = "invitee_id", nullable = true)
        @ForeignKey(enabled = true)
        private User invitee;
@@ -117,16 +117,16 @@ public class Invitation implements IData
        @Column(name = "valid")
        @Enumerated(EnumType.STRING)
        private Valid valid = Valid.Period;
-       
+
        @Column(name = "valid_from")
        private Date validFrom;
-       
+
        @Column(name = "valid_to")
        private Date validTo;
-       
+
        @Column(name = "was_used", nullable = false)
        private boolean used;
-       
+
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "appointment_id", nullable = true)
        @ForeignKey(enabled = true)
@@ -135,9 +135,9 @@ public class Invitation implements IData
        //variable used in Flash
        @Transient
        private boolean allowEntry = true;
-       
+
        public Invitation() {}
-       
+
        public Invitation(Invitation i) {
                id = i.id;
                invitedBy = i.invitedBy;
@@ -156,7 +156,7 @@ public class Invitation implements IData
                used = i.used;
                appointment = i.appointment;
        }
-       
+
        @Override
        public Long getId() {
                return id;
@@ -286,7 +286,7 @@ public class Invitation implements IData
        public void setValid(Valid valid) {
                this.valid = valid;
        }
-       
+
        public boolean isAllowEntry() {
                return allowEntry;
        }

Modified: 
openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
 (original)
+++ 
openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
 Wed Jan 25 12:02:26 2017
@@ -489,7 +489,7 @@ public class Application extends Authent
                        if (r.isAppointment() && 
i.getInvitedBy().getId().equals(u.getId())) {
                                link = getRoomUrlFragment(r.getId()).getLink();
                        } else {
-                               boolean allowed = u.getType() != Type.contact;
+                               boolean allowed = Type.contact != u.getType() 
&& Type.external != u.getType();
                                if (allowed) {
                                        allowed = 
getBean(MainService.class).isRoomAllowedToUser(r, u);
                                }

Modified: 
openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
 (original)
+++ 
openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/calendar/TestAppointmentAddAppointment.java
 Wed Jan 25 12:02:26 2017
@@ -56,7 +56,7 @@ public class TestAppointmentAddAppointme
        @Autowired
        private UserDao userDao;
 
-       private void setTime(Appointment a) {
+       private static 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()));
        }

Modified: 
openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
 (original)
+++ 
openmeetings/application/trunk/openmeetings-web/src/test/java/org/apache/openmeetings/test/webservice/TestCalendarService.java
 Wed Jan 25 12:02:26 2017
@@ -19,21 +19,29 @@
 package org.apache.openmeetings.test.webservice;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.UUID;
 
 import javax.ws.rs.core.Form;
 import javax.ws.rs.core.Response;
 
+import org.apache.openmeetings.db.dao.calendar.MeetingMemberDao;
+import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
 import org.apache.openmeetings.db.dao.user.GroupDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
 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.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
@@ -49,6 +57,12 @@ public class TestCalendarService extends
        private GroupDao groupDao;
        @Autowired
        private RoomDao roomDao;
+       @Autowired
+       private MeetingMemberDao mmDao;
+       @Autowired
+       private InvitationDao invitationDao;
+       @Autowired
+       private UserDao userDao;
 
        private void actualTest(Room r) throws Exception {
                String uuid = UUID.randomUUID().toString();
@@ -78,10 +92,10 @@ public class TestCalendarService extends
        private static JSONObject createAppointment() {
                return new JSONObject()
                        .put("title", "test")
-                       .put("start", "2017-01-20T20:30:03+0300")
-                       .put("end", "2017-01-20T21:30:03+0300")
+                       .put("start", "2025-01-20T20:30:03+0300")
+                       .put("end", "2025-01-20T21:30:03+0300")
                        .put("description", "Русский Тест")
-                       .put("reminder", "none")
+                       .put("reminder", "email")
                        .put("room", new JSONObject()
                                        .put("name", "test24")
                                        .put("comment", "appointment test room")
@@ -112,19 +126,24 @@ public class TestCalendarService extends
                        .put("reminderEmailSend", false);
        }
 
-       @Test
-       public void testCreate() throws Exception {
-               JSONObject o = createAppointment();
-
+       private String loginNewUser() throws Exception {
                String uuid = UUID.randomUUID().toString();
                User u = getUser(uuid);
                u.getGroupUsers().add(new GroupUser(groupDao.get(1L), u));
                u = createUser(u);
                ServiceResult sr = login(u.getLogin(), getRandomPass(uuid));
+               return sr.getMessage();
+       }
+
+       @Test
+       public void testCreate() throws Exception {
+               JSONObject o = createAppointment();
+
+               String sid = loginNewUser();
 
                Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -170,31 +189,24 @@ public class TestCalendarService extends
                assertNotNull("DTO id should be valid", dto.getId());
        }
 
-       @Test
-       public void testCreateWithMm() throws Exception {
+       private static AppointmentDTO createEventWithGuests(String sid) throws 
Exception {
                JSONObject o = createAppointment()
                                .put("meetingMembers", new JSONArray()
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                
.put("firstname", "John 1")
                                                                
.put("lastname", "Doe")
-                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
+                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
                                                                ))
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                
.put("firstname", "John 2")
                                                                
.put("lastname", "Doe")
-                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
+                                                               .put("address", 
new JSONObject().put("email", "[email protected]"))
                                                                ))
                                                );
 
-               String uuid = UUID.randomUUID().toString();
-               User u = getUser(uuid);
-               u.getGroupUsers().add(new GroupUser(groupDao.get(1L), u));
-               u = createUser(u);
-               ServiceResult sr = login(u.getLogin(), getRandomPass(uuid));
-
                Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -207,15 +219,23 @@ public class TestCalendarService extends
                        assertNotNull("Email should be valid", 
mm.getUser().getAddress().getEmail());
                }
 
+               return dto;
+       }
+
+       @Test
+       public void testCreateWithGuests() throws Exception {
+               String sid = loginNewUser();
+               AppointmentDTO dto = createEventWithGuests(sid);
+
                //try to change MM list
                JSONObject o1 = AppointmentParamConverter.json(dto)
                                .put("meetingMembers", new JSONArray()
                                                .put(new 
JSONObject().put("user", new JSONObject()
                                                                .put("id", 
1))));
 
-               resp = getClient(CALENDAR_SERVICE_URL)
+               Response resp = getClient(CALENDAR_SERVICE_URL)
                                .path("/")
-                               .query("sid", sr.getMessage())
+                               .query("sid", sid)
                                .form(new Form().param("appointment", 
o1.toString()));
 
                assertNotNull("Valid AppointmentDTO should be returned", resp);
@@ -225,4 +245,35 @@ public class TestCalendarService extends
                assertNotNull("DTO id should be valid", dto.getId());
                assertEquals("DTO should have 1 attendees", 1, 
dto.getMeetingMembers().size());
        }
+
+       @Test
+       public void testCreateWithGuestsCleanOne() throws Exception {
+               String sid = loginNewUser();
+               AppointmentDTO dto = createEventWithGuests(sid);
+               List<MeetingMemberDTO> initialList = new 
ArrayList<>(dto.getMeetingMembers());
+               MeetingMember mm = mmDao.get(initialList.get(initialList.size() 
- 1).getId());
+               Long mmId = mm.getId(), mmUserId = mm.getUser().getId();
+               String hash = mm.getInvitation().getHash();
+               dto.getMeetingMembers().remove(initialList.size() - 1);
+
+               //try to change MM list
+               JSONObject o = AppointmentParamConverter.json(dto);
+               Response resp = getClient(CALENDAR_SERVICE_URL)
+                               .path("/")
+                               .query("sid", sid)
+                               .form(new Form().param("appointment", 
o.toString()));
+
+               assertNotNull("Valid AppointmentDTO should be returned", resp);
+               assertEquals("Call should be successful", 
Response.Status.OK.getStatusCode(), resp.getStatus());
+               dto = resp.readEntity(AppointmentDTO.class);
+               assertNotNull("Valid DTO should be returned", dto);
+               assertNotNull("DTO id should be valid", dto.getId());
+               assertEquals("DTO should have 1 attendees", 1, 
dto.getMeetingMembers().size());
+
+               assertNull("Meeting member should deleted", mmDao.get(mmId));
+               assertNull("Invitation should deleted", 
invitationDao.getByHash(hash, true, false));
+               User uc = userDao.get(mmUserId);
+               assertNotNull("Meeting member user should not be deleted", uc);
+               assertFalse("Meeting member user should not be deleted", 
uc.isDeleted());
+       }
 }

Modified: 
openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java
URL: 
http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java?rev=1780175&r1=1780174&r2=1780175&view=diff
==============================================================================
--- 
openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java
 (original)
+++ 
openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/util/AppointmentParamConverter.java
 Wed Jan 25 12:02:26 2017
@@ -69,7 +69,7 @@ public class AppointmentParamConverter i
 
        public static JSONObject json(AppointmentDTO val) {
                Date i = val.getInserted(), u = val.getUpdated();
-               return new JSONObject(val)
+               JSONObject o = new JSONObject(val)
                                .put("owner", UserDTO.json(val.getOwner()))
                                .put("room", RoomDTO.json(val.getRoom()))
                                .put("reminder", val.getReminder() == null ? 
null : val.getReminder().name())
@@ -77,6 +77,14 @@ public class AppointmentParamConverter i
                                .put("end", 
ISO8601_FULL_FORMAT.format(val.getEnd()))
                                .put("inserted", i == null ? null : 
ISO8601_FULL_FORMAT.format(i))
                                .put("updated", u == null ? null : 
ISO8601_FULL_FORMAT.format(u));
+               if (val.getMeetingMembers() != null) {
+                       JSONArray rr = new JSONArray();
+                       for(MeetingMemberDTO mm : val.getMeetingMembers()) {
+                               rr.put(MeetingMemberDTO.json(mm));
+                       }
+                       o.put("meetingMembers", rr);
+               }
+               return o;
        }
 
        @Override


Reply via email to