Hello Sebastian, I'm afraid we need something like "lightweight RoomClient" in the DB to resolve 3) This can be done without performance degradation. I see no other way to get the number of users.
On Wed, Oct 24, 2012 at 3:31 PM, [email protected] < [email protected]> wrote: > So will we find a consens here? :) > > 1) No DB query in Sync methods to keep performance up > 2) Session objects should not stay in a database but in memory > 3) To have the number of users per server instance there is no need to > have the RoomClient in the database. > > Can we find a consens based on those resolutions? > > Sebastian > > 2012/10/22 [email protected] <[email protected]> > > Practically in this case you would have to iterate thorugh the connection. >> You could also call IConnection => getConnection => getSize. >> This would give a rough idea. But as you don't know how many of those >> connection are screensharing or Audio/Video you can't tell how many users >> exactly there are. >> >> If you want to share this information with others I would suggest you >> simply add a SOAP/REST call and in that sense query the number of users via >> a HTTP call. >> >> >> Sebastian >> >> 2012/10/22 Maxim Solodovnik <[email protected]> >> >>> If I remember correctly I have added RoomClient to the DB since I need >>> mechanism to retrieve how much users are currently in the room. >>> >>> >>> On Mon, Oct 22, 2012 at 3:23 PM, [email protected] < >>> [email protected]> wrote: >>> >>>> We could even store it currently in the IConnection. The Red5 framework >>>> has the similar mechanism like the static Map that I've build. >>>> >>>> We will also stay with our Red5 implementation for the next 6 months as >>>> we have no alternative to stream audio/video in HTML5. >>>> >>>> It is no option to stay with it, how can we offer OpenMeetings to be >>>> scalable to 1000 concurrent users? We would have to limit it to 250. Also >>>> it would become mandatory to have the database server on the same machine >>>> as the red5 server. Otherwise you have performance bottlenecks. Can you >>>> imagine what kind of negative public feedback we will have if every >>>> question about performance of red5 is answered with: Did you install db >>>> server on another instance of your network? >>>> >>>> Sorry but it is not possible. Also not for a temporary solution. We >>>> can't sell this product like that and claim to have 1000 user sessions per >>>> server unit. >>>> >>>> What requirements do exist to store the RoomClient in the database and >>>> what is needed to be done to remove it from the db again? >>>> >>>> >>>> Sebastian >>>> >>>> 2012/10/22 Maxim Solodovnik <[email protected]> >>>> >>>>> OK, I'm not insist. I believe RoomClient will be removed in the future. >>>>> >>>>> >>>>> On Mon, Oct 22, 2012 at 3:00 PM, [email protected] < >>>>> [email protected]> wrote: >>>>> >>>>>> Sorry but: >>>>>> >>>>>> for (RoomClient rc: allClient) { >>>>>> if (rc.getPublicSID().equals(_publicSID) { >>>>>> return rc; >>>>>> } >>>>>> } >>>>>> >>>>>> That is simply not true. >>>>>> There are _some_ implementations where it was needed that you need to >>>>>> get the RoomClient by its public SID. However this usage was quite >>>>>> limited. >>>>>> >>>>>> In general it was the way I described it: >>>>>> The maps key was the streamid. And the streamid was obtained from the >>>>>> IConnection of each stream. >>>>>> >>>>>> >>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup >>>>>> Line 118, that was the function that was mainly in use all over the >>>>>> application. >>>>>> There is no sorting, there is no iteration => nothing. >>>>>> >>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" => 52 >>>>>> of matches. >>>>>> Every of this call is now replaced by a single DB query. >>>>>> And if you iterate like described through all connection (like it is >>>>>> in EVERY snyc method) >>>>>> You will do a single query for EVERY connection. >>>>>> Like 100 users in a room => 100 queries. >>>>>> Think about the green dot that blinks every time you speak in the >>>>>> video pod: >>>>>> If it gets visible => one sync message >>>>>> If its get transparent => one sync message. >>>>>> If you have a quite good and sensitive micro it will flush 10 mabye >>>>>> 10 times per second. >>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE SECOND >>>>>> => that is just impossible !! >>>>>> And that is just a SINGLE videopod with 100 users watching. Now scale >>>>>> that up to 1000 concurrent rooms with 4x4 meetings where every user has >>>>>> micro turned on ?! Should we calc the number of database queries really?! >>>>>> >>>>>> Sorry we will not follow that route :) >>>>>> >>>>>> Sebastian >>>>>> >>>>>> 2012/10/22 Maxim Solodovnik <[email protected]> >>>>>> >>>>>>> Previous solution was: >>>>>>> >>>>>>> for (RoomClient rc: allClient) { >>>>>>> if (rc.getPublicSID().equals(_publicSID) { >>>>>>> return rc; >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> + screen sharing clients were filtered same way. >>>>>>> Right now we can filter all sessions with 1 query this is why the >>>>>>> code can work faster (after minor changes in iterating logic) >>>>>>> >>>>>>> I'm not insist RoomClient should be DB object. But having it as DB >>>>>>> object was the only option to have user count in the room (in case Rooms >>>>>>> are on the different servers). >>>>>>> >>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession will >>>>>>> be session object. >>>>>>> I hope everything except audio and video will move to Wicket :) >>>>>>> >>>>>>> >>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, [email protected] < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> Hi Maxim, >>>>>>>> >>>>>>>> you can't persist on the argumentation that a HashMap stored in the >>>>>>>> memory is slower then doing a single query for every entry of the map ? >>>>>>>> Basicaly the previous implementation was a single HashMap. >>>>>>>> Getting a RoomClient from this map was: >>>>>>>> map.get($streamId) >>>>>>>> and now this single line is replaced by a Database query. The >>>>>>>> performance of this single line is ... I guess smaller then 1 >>>>>>>> millisecond. >>>>>>>> How can you say that a "Right now I think the current code should work >>>>>>>> faster or the same as previous one." :) >>>>>>>> >>>>>>>> I guess you had some other requirements that made you implement >>>>>>>> this. >>>>>>>> For example for the clustering solution. >>>>>>>> However I also persist on my view: >>>>>>>> A database is _not_ the right place for storing session variables. >>>>>>>> This is simply a bad design decision that will cost a lot of >>>>>>>> performance in >>>>>>>> the future. >>>>>>>> >>>>>>>> Could you explain why there is a need for having the RoomClient in >>>>>>>> the database? Maybe we can resolve those requirements differently so >>>>>>>> that >>>>>>>> we can have the RoomClient back in memory. >>>>>>>> >>>>>>>> Sebastian >>>>>>>> >>>>>>>> >>>>>>>> 2012/10/19 Maxim Solodovnik <[email protected]> >>>>>>>> >>>>>>>>> Sorry for double post. >>>>>>>>> >>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML >>>>>>>>> export/import" is not necessary since it doesn't have @Element >>>>>>>>> annotation >>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <[email protected]> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster. >>>>>>>>>> Current changes only make the calls faster (since DB is quered >>>>>>>>>> only once) >>>>>>>>>> >>>>>>>>>> I'll try to create couple of tests. Right now I think the current >>>>>>>>>> code should work faster or the same as previous one. >>>>>>>>>> >>>>>>>>>> Old code did lots of full filterings of RommsClient hash map to >>>>>>>>>> get subset required. >>>>>>>>>> >>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa >>>>>>>>>> cache and if it doesn't help will split RoomClient to the couple of >>>>>>>>>> objects >>>>>>>>>> and/or will create hashtable in parallel to speed up things. >>>>>>>>>> >>>>>>>>>> But I hope everything is not so slow since these changes are >>>>>>>>>> present in 2.0 and nobody reports performance degradation. >>>>>>>>>> >>>>>>>>>> Sorry for typos, I'm from mobile phone >>>>>>>>>> On Oct 19, 2012 9:11 PM, "[email protected]" < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> I guess this happened lately in trunk. >>>>>>>>>>> How are we the in the future planning to determine the current >>>>>>>>>>> users in the room. >>>>>>>>>>> Session or database based? >>>>>>>>>>> >>>>>>>>>>> I ask that critical as some queries require to sync messages to >>>>>>>>>>> all clients of a room. >>>>>>>>>>> This can happen 1000 times in a single second if you think about >>>>>>>>>>> having up to 1000 concurrent user sessions. >>>>>>>>>>> >>>>>>>>>>> For example: >>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String >>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean >>>>>>>>>>> sendScreen) >>>>>>>>>>> => Collection<Set<IConnection>> conCollection = >>>>>>>>>>> current.getScope() >>>>>>>>>>> .getConnections(); >>>>>>>>>>> ==> iterates through all connection of the scope. >>>>>>>>>>> >>>>>>>>>>> Now the new thing is that for every connection you will create a >>>>>>>>>>> query for the RoomClient Object. >>>>>>>>>>> This is simply impossible. >>>>>>>>>>> >>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more. >>>>>>>>>>> The RoomClient is a typical Session object and it should stay in >>>>>>>>>>> the session. >>>>>>>>>>> It is the same issue like with the WhiteboardObject. >>>>>>>>>>> We are making a real time application, there is no chance to run >>>>>>>>>>> queries in sync methods. >>>>>>>>>>> >>>>>>>>>>> Can we find some consens here? I know you must have refactored >>>>>>>>>>> already a lot but I strictly did implement zero db related stuff in >>>>>>>>>>> sync >>>>>>>>>>> methods. >>>>>>>>>>> >>>>>>>>>>> There might be a chance for some events to trigger db >>>>>>>>>>> actions.However I don't think having two times the RoomClient >>>>>>>>>>> stored (one >>>>>>>>>>> time session, second time database) makes sense. >>>>>>>>>>> >>>>>>>>>>> What are you thoughts on this? >>>>>>>>>>> >>>>>>>>>>> Sebastian >>>>>>>>>>> >>>>>>>>>>> 2012/10/19 [email protected] <[email protected]> >>>>>>>>>>> >>>>>>>>>>>> Hi Maxim, >>>>>>>>>>>> >>>>>>>>>>>> I don't understand this new code in the Rooms Entity: >>>>>>>>>>>> @OneToMany(fetch = FetchType.LAZY) >>>>>>>>>>>> >>>>>>>>>>>> @JoinColumn(name = "room_id") >>>>>>>>>>>> private List<RoomClient> currentusers; >>>>>>>>>>>> >>>>>>>>>>>> We calc the current users online by iterating through the Red5 >>>>>>>>>>>> Connections. >>>>>>>>>>>> In which OpenMeetings version was it changed? >>>>>>>>>>>> >>>>>>>>>>>> I guess you can set it Transient for XML export/import. So >>>>>>>>>>>> maybe annotate it with: >>>>>>>>>>>> @org.simpleframework.xml.Transient >>>>>>>>>>>> same like roomOrganisations. >>>>>>>>>>>> >>>>>>>>>>>> Sebastian >>>>>>>>>>>> >>>>>>>>>>>> 2012/10/19 <[email protected]> >>>>>>>>>>>> >>>>>>>>>>>> Author: solomax >>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012 >>>>>>>>>>>>> New Revision: 1400075 >>>>>>>>>>>>> >>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev >>>>>>>>>>>>> Log: >>>>>>>>>>>>> Wicket: calendar form is improved >>>>>>>>>>>>> >>>>>>>>>>>>> Modified: >>>>>>>>>>>>> >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>>>>>>>>>>>> >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>>>>>>>>>>>> >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>>>>>>>>>>>> >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>>>>>>>>>>>> >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>>>>>>>>>>>> >>>>>>>>>>>>> Modified: >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>>>>>>>>>>>> URL: >>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>>>>>>>>>>>> >>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>> --- >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>>>>>>>>>>>> (original) >>>>>>>>>>>>> +++ >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java >>>>>>>>>>>>> Fri Oct 19 12:39:38 2012 >>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro >>>>>>>>>>>>> return q.getSingleResult(); >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> + public List<Rooms> getPublicRooms() { >>>>>>>>>>>>> + //TypedQuery<Rooms> q = >>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class); >>>>>>>>>>>>> + TypedQuery<Rooms> q = em.createQuery( >>>>>>>>>>>>> + "SELECT r from Rooms r LEFT >>>>>>>>>>>>> JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= >>>>>>>>>>>>> false ORDER >>>>>>>>>>>>> BY r.name ASC", Rooms.class); >>>>>>>>>>>>> + return q.getResultList(); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + public List<Rooms> getOrganisationRooms(long orgId) { >>>>>>>>>>>>> + TypedQuery<Rooms> q = em.createQuery( >>>>>>>>>>>>> + "SELECT DISTINCT c.room FROM >>>>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH >>>>>>>>>>>>> c.room.currentusers " >>>>>>>>>>>>> + + "WHERE c.organisation.organisation_id = >>>>>>>>>>>>> :orgId " >>>>>>>>>>>>> + + "AND c.deleted = false AND c.room.deleted = >>>>>>>>>>>>> false " >>>>>>>>>>>>> + + "AND c.organisation.deleted = false " >>>>>>>>>>>>> + + "ORDER BY c.room.name ASC", Rooms.class); >>>>>>>>>>>>> + q.setParameter("orgId", orgId); >>>>>>>>>>>>> + return q.getResultList(); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> public Rooms update(Rooms entity, long userId) { >>>>>>>>>>>>> if (entity.getRooms_id() == null) { >>>>>>>>>>>>> /* Red5SIP integration >>>>>>>>>>>>> *******************************************************************************/ >>>>>>>>>>>>> >>>>>>>>>>>>> Modified: >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>>>>>>>>>>>> URL: >>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>>>>>>>>>>>> >>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>> --- >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>>>>>>>>>>>> (original) >>>>>>>>>>>>> +++ >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java >>>>>>>>>>>>> Fri Oct 19 12:39:38 2012 >>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery; >>>>>>>>>>>>> import javax.persistence.OneToMany; >>>>>>>>>>>>> import javax.persistence.OneToOne; >>>>>>>>>>>>> import javax.persistence.Table; >>>>>>>>>>>>> -import javax.persistence.Transient; >>>>>>>>>>>>> >>>>>>>>>>>>> import org.apache.openjpa.persistence.ElementDependent; >>>>>>>>>>>>> import org.apache.openmeetings.persistence.beans.OmEntity; >>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab >>>>>>>>>>>>> private String name; >>>>>>>>>>>>> >>>>>>>>>>>>> @Lob >>>>>>>>>>>>> - // @Basic(fetch=FetchType.LAZY) >>>>>>>>>>>>> @Column(name = "comment_field") >>>>>>>>>>>>> @Element(data = true, required = false) >>>>>>>>>>>>> private String comment; >>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab >>>>>>>>>>>>> @org.simpleframework.xml.Transient >>>>>>>>>>>>> private List<Rooms_Organisation> roomOrganisations = >>>>>>>>>>>>> new ArrayList<Rooms_Organisation>(); >>>>>>>>>>>>> >>>>>>>>>>>>> - /* >>>>>>>>>>>>> - * Non persistent attributes >>>>>>>>>>>>> - */ >>>>>>>>>>>>> - @Transient >>>>>>>>>>>>> + @OneToMany(fetch = FetchType.LAZY) >>>>>>>>>>>>> + @JoinColumn(name = "room_id") >>>>>>>>>>>>> private List<RoomClient> currentusers; >>>>>>>>>>>>> >>>>>>>>>>>>> public String getComment() { >>>>>>>>>>>>> >>>>>>>>>>>>> Modified: >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>>>>>>>>>>>> URL: >>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>>>>>>>>>>>> >>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>> --- >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>>>>>>>>>>>> (original) >>>>>>>>>>>>> +++ >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java >>>>>>>>>>>>> Fri Oct 19 12:39:38 2012 >>>>>>>>>>>>> @@ -18,14 +18,36 @@ >>>>>>>>>>>>> */ >>>>>>>>>>>>> package org.apache.openmeetings.web.components.user.calendar; >>>>>>>>>>>>> >>>>>>>>>>>>> +import java.util.ArrayList; >>>>>>>>>>>>> +import java.util.List; >>>>>>>>>>>>> + >>>>>>>>>>>>> +import >>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl; >>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO; >>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.Roommanagement; >>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl; >>>>>>>>>>>>> import >>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment; >>>>>>>>>>>>> +import >>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps; >>>>>>>>>>>>> +import >>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users; >>>>>>>>>>>>> +import >>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes; >>>>>>>>>>>>> +import org.apache.openmeetings.persistence.beans.rooms.Rooms; >>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application; >>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession; >>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget; >>>>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; >>>>>>>>>>>>> +import >>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField; >>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer; >>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice; >>>>>>>>>>>>> import org.apache.wicket.markup.html.form.Form; >>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField; >>>>>>>>>>>>> import org.apache.wicket.markup.html.form.RequiredTextField; >>>>>>>>>>>>> import org.apache.wicket.markup.html.form.TextArea; >>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField; >>>>>>>>>>>>> import org.apache.wicket.model.IModel; >>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel; >>>>>>>>>>>>> >>>>>>>>>>>>> public class CalendarForm extends Form<Appointment> { >>>>>>>>>>>>> private static final long serialVersionUID = >>>>>>>>>>>>> -1764738237821487526L; >>>>>>>>>>>>> + private boolean createRoom = true; >>>>>>>>>>>>> >>>>>>>>>>>>> public CalendarForm(String id, IModel<Appointment> >>>>>>>>>>>>> model) { >>>>>>>>>>>>> super(id, model); >>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A >>>>>>>>>>>>> >>>>>>>>>>>>> add(new >>>>>>>>>>>>> RequiredTextField<String>("appointmentName")); >>>>>>>>>>>>> add(new >>>>>>>>>>>>> TextArea<String>("appointmentDescription")); >>>>>>>>>>>>> + add(new >>>>>>>>>>>>> TextField<String>("appointmentLocation")); >>>>>>>>>>>>> + add(new DateTimeField("appointmentStarttime")); >>>>>>>>>>>>> + add(new DateTimeField("appointmentEndtime")); >>>>>>>>>>>>> + final PasswordTextField pwd = new >>>>>>>>>>>>> PasswordTextField("password"); >>>>>>>>>>>>> + pwd.setEnabled(isPwdProtected()); >>>>>>>>>>>>> + pwd.setOutputMarkupId(true); >>>>>>>>>>>>> + add(pwd); >>>>>>>>>>>>> + >>>>>>>>>>>>> + add(new >>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>( >>>>>>>>>>>>> + "remind" >>>>>>>>>>>>> + , >>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList() >>>>>>>>>>>>> + , new >>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId"))); >>>>>>>>>>>>> + >>>>>>>>>>>>> + final DropDownChoice<RoomTypes> roomType = new >>>>>>>>>>>>> DropDownChoice<RoomTypes>( >>>>>>>>>>>>> + "room.roomtype" >>>>>>>>>>>>> + , >>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes() >>>>>>>>>>>>> + , new >>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id")); >>>>>>>>>>>>> + roomType.setEnabled(createRoom); >>>>>>>>>>>>> + roomType.setOutputMarkupId(true); >>>>>>>>>>>>> + add(roomType); >>>>>>>>>>>>> + >>>>>>>>>>>>> + final DropDownChoice<Rooms> room = new >>>>>>>>>>>>> DropDownChoice<Rooms>( >>>>>>>>>>>>> + "room" >>>>>>>>>>>>> + , getRoomList() >>>>>>>>>>>>> + , new >>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id")); >>>>>>>>>>>>> + room.setEnabled(!createRoom); >>>>>>>>>>>>> + room.setOutputMarkupId(true); >>>>>>>>>>>>> + add(room); >>>>>>>>>>>>> + >>>>>>>>>>>>> + add(new AjaxCheckBox("createRoom", new >>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) { >>>>>>>>>>>>> + private static final long >>>>>>>>>>>>> serialVersionUID = -3743113990890386035L; >>>>>>>>>>>>> + >>>>>>>>>>>>> + @Override >>>>>>>>>>>>> + protected void >>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) { >>>>>>>>>>>>> + createRoom = >>>>>>>>>>>>> getConvertedInput(); >>>>>>>>>>>>> + >>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), >>>>>>>>>>>>> room.setEnabled(!createRoom)); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + }); >>>>>>>>>>>>> + add(new AjaxCheckBox("isPasswordProtected") { >>>>>>>>>>>>> + private static final long >>>>>>>>>>>>> serialVersionUID = 6041200584296439976L; >>>>>>>>>>>>> + >>>>>>>>>>>>> + @Override >>>>>>>>>>>>> + protected void >>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) { >>>>>>>>>>>>> + >>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput()); >>>>>>>>>>>>> + >>>>>>>>>>>>> pwd.setEnabled(isPwdProtected()); >>>>>>>>>>>>> + target.add(pwd); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + }); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + private boolean isPwdProtected() { >>>>>>>>>>>>> + return >>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected()); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + >>>>>>>>>>>>> + private List<Rooms> getRoomList() { >>>>>>>>>>>>> + //FIXME need to be reviewed >>>>>>>>>>>>> + List<Rooms> result = new ArrayList<Rooms>(); >>>>>>>>>>>>> + RoomDAO dao = >>>>>>>>>>>>> Application.getBean(RoomDAO.class); >>>>>>>>>>>>> + result.addAll(dao.getPublicRooms()); >>>>>>>>>>>>> + for (Organisation_Users ou : >>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users()) >>>>>>>>>>>>> { >>>>>>>>>>>>> + >>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id())); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + if (getModelObject().getRoom() != null && >>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review >>>>>>>>>>>>> + result.add(getModelObject().getRoom()); >>>>>>>>>>>>> + } >>>>>>>>>>>>> + return result; >>>>>>>>>>>>> } >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> Modified: >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>>>>>>>>>>>> URL: >>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff >>>>>>>>>>>>> >>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>> --- >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>>>>>>>>>>>> (original) >>>>>>>>>>>>> +++ >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html >>>>>>>>>>>>> Fri Oct 19 12:39:38 2012 >>>>>>>>>>>>> @@ -71,7 +71,7 @@ >>>>>>>>>>>>> $('#appointment').dialog({ >>>>>>>>>>>>> closeOnEscape: true >>>>>>>>>>>>> , resizable: true >>>>>>>>>>>>> - , width: 400 >>>>>>>>>>>>> + , width: 450 >>>>>>>>>>>>> , autoOpen: false >>>>>>>>>>>>> , modal: true >>>>>>>>>>>>> }); >>>>>>>>>>>>> @@ -89,53 +89,55 @@ >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td> >>>>>>>>>>>>> <td><input >>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> - <!-- tr> >>>>>>>>>>>>> - <td> </td> >>>>>>>>>>>>> - <td> >>>>>>>>>>>>> - >>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text" >>>>>>>>>>>>> wicket:id="appointmentStarttime" /> >>>>>>>>>>>>> - >>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text" >>>>>>>>>>>>> wicket:id="appointmentEndtime" /> >>>>>>>>>>>>> - </td> >>>>>>>>>>>>> + <tr> >>>>>>>>>>>>> + >>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td> >>>>>>>>>>>>> + <td><span >>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td> >>>>>>>>>>>>> + </tr> >>>>>>>>>>>>> + <tr> >>>>>>>>>>>>> + >>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td> >>>>>>>>>>>>> + <td><span >>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td> >>>>>>>>>>>>> - <td><select >>>>>>>>>>>>> wicket:id="notification" ></select></td> >>>>>>>>>>>>> + <td><select >>>>>>>>>>>>> wicket:id="remind" ></select></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> <td >>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom" >>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td> >>>>>>>>>>>>> - <td><select >>>>>>>>>>>>> wicket:id="roomType" ></select></td> >>>>>>>>>>>>> + <td><select >>>>>>>>>>>>> wicket:id="room.roomtype" ></select></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td> >>>>>>>>>>>>> <td><select >>>>>>>>>>>>> wicket:id="room" ></select></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> - <td >>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected" >>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td> >>>>>>>>>>>>> + <td >>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="isPasswordProtected" >>>>>>>>>>>>> /><wicket:ommessage key="524" /></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td> >>>>>>>>>>>>> - <td><input >>>>>>>>>>>>> type="text" wicket:id="password" /></td> >>>>>>>>>>>>> + <td><input >>>>>>>>>>>>> type="password" wicket:id="password" /></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> <td >>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> + <!-- >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td> >>>>>>>>>>>>> <td><select >>>>>>>>>>>>> wicket:id="meetingMember" ></select></td> >>>>>>>>>>>>> - </tr> >>>>>>>>>>>>> + </tr --> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td> >>>>>>>>>>>>> <td><input >>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td> >>>>>>>>>>>>> - </tr--> >>>>>>>>>>>>> + </tr> >>>>>>>>>>>>> <tr> >>>>>>>>>>>>> >>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td> >>>>>>>>>>>>> - <td><input >>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td> >>>>>>>>>>>>> + <td><textarea >>>>>>>>>>>>> wicket:id="appointmentDescription"></textarea></td> >>>>>>>>>>>>> </tr> >>>>>>>>>>>>> <!-- tr> >>>>>>>>>>>>> <td >>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" >>>>>>>>>>>>> wicket:id="save" >>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td> >>>>>>>>>>>>> - </tr--> >>>>>>>>>>>>> + </tr --> >>>>>>>>>>>>> </table> >>>>>>>>>>>>> </form> >>>>>>>>>>>>> </div> >>>>>>>>>>>>> >>>>>>>>>>>>> Modified: >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>>>>>>>>>>>> URL: >>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff >>>>>>>>>>>>> >>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>> --- >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>>>>>>>>>>>> (original) >>>>>>>>>>>>> +++ >>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java >>>>>>>>>>>>> Fri Oct 19 12:39:38 2012 >>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP >>>>>>>>>>>>> Calendar end = >>>>>>>>>>>>> WebSession.getCalendar(); >>>>>>>>>>>>> >>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong()); >>>>>>>>>>>>> >>>>>>>>>>>>> + if (start.equals(end)) { >>>>>>>>>>>>> + >>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1); >>>>>>>>>>>>> + } >>>>>>>>>>>>> Appointment a = new >>>>>>>>>>>>> Appointment(); >>>>>>>>>>>>> >>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime()); >>>>>>>>>>>>> >>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime()); >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Sebastian Wagner >>>>>>>>>>>> https://twitter.com/#!/dead_lock >>>>>>>>>>>> http://www.webbase-design.de >>>>>>>>>>>> http://www.wagner-sebastian.com >>>>>>>>>>>> [email protected] >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Sebastian Wagner >>>>>>>>>>> https://twitter.com/#!/dead_lock >>>>>>>>>>> http://www.webbase-design.de >>>>>>>>>>> http://www.wagner-sebastian.com >>>>>>>>>>> [email protected] >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Sebastian Wagner >>>>>>>> https://twitter.com/#!/dead_lock >>>>>>>> http://www.webbase-design.de >>>>>>>> http://www.wagner-sebastian.com >>>>>>>> [email protected] >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> WBR >>>>>>> Maxim aka solomax >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Sebastian Wagner >>>>>> https://twitter.com/#!/dead_lock >>>>>> http://www.webbase-design.de >>>>>> http://www.wagner-sebastian.com >>>>>> [email protected] >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> WBR >>>>> Maxim aka solomax >>>>> >>>> >>>> >>>> >>>> -- >>>> Sebastian Wagner >>>> https://twitter.com/#!/dead_lock >>>> http://www.webbase-design.de >>>> http://www.wagner-sebastian.com >>>> [email protected] >>>> >>> >>> >>> >>> -- >>> WBR >>> Maxim aka solomax >>> >> >> >> >> -- >> Sebastian Wagner >> https://twitter.com/#!/dead_lock >> http://www.webbase-design.de >> http://www.wagner-sebastian.com >> [email protected] >> > > > > -- > Sebastian Wagner > https://twitter.com/#!/dead_lock > http://www.webbase-design.de > http://www.wagner-sebastian.com > [email protected] > -- WBR Maxim aka solomax
