Howto implement temporary changes / rollback in my model?

First some background information: I'm building a project management tool. It's based on JEE, Struts 2 and uses AJAX. The model exists as a singleton within the application-server. The model is basically an object tree which consists of projects, releases, usecases, tasks, team members and employees. The model uses the observer pattern to update data when it's necessary. For instance if you change the amount of work required to solve a task, the total amount of work to finish the usecase and the total amount of work to finish the release are updated.
I've got a dialog where a user can add and remove team members from a task and set multiple attributes on each team member. All these changes will affect the whole model (for instance, if you add an employee to the task-team this has an effect on the availability of this employee for other tasks). In the UI the user will see the result of his actions immediately, for that i need to update the model. But, what if the user hits the Cancel button? Or worse, leaves the dialog open and closes the browser? In that case I need to rollback my model. But since it's almost impossible to notice the closing of the browser reliably, rollback is not an option. So the best thing would be to work on a temporary model when the dialog opens. Then the user may change whatever he wants, and when he finally hits the OK button the temporary model needs to be merged with the "real" singleton-model (Since another user may have changed something in another task).
Now to my question: How would you implement this? Is there a pattern one could use? Do I really have to clone the whole object tree or is there a better way to solve this?
Thanks for your replies,
André

Thanks for your answers. They gave me some fresh ideas.
Both approaches go into the same direction somehow. I like the idea of having a simple facade, that hides the complex stuff (like the copy-on-write implementation). Anyway, it really looks like my singleton implementation is too simple for what I'm doing here sigh.

Similar Messages

  • Implementing Dirty Flag for a generated Model (Flex 4)

    Hi there,
    I try to implement a dirty flag for a model generated by a Data Binding Wizard. I tried several ways but always failed to get it work properly bounded to the 'enabled' property of a button. Is there a "best approach" to implement this in a by Flex 4 generated model?
    I have all the Form elements bound to the model's properties and defined fx:Bindings on the model's property as well to get the changes back to the model as well.
    -> I tried to listen to the properyChange event on the Super model but I always returned true for the Dirty flag and couldn't set it to false when I loaded the model into a Form.
    -> I tried to implement a similar approach like below, instead of doing a normal 'getter' function on the isDirty flag I bounded it to the propertyChange event, it failed exactly the same way as above
    I did used my own solution earlier like this:
    [RemoteClass(alias="VODictionaryEntry")]
         [Bindable]
         public class VODictionaryEntry
                   private var _id:Number = 0;
                   private var _terminology:String;
                   private var _description:String;
                   private var _notes:String;
                   private var _insert_date:String;
                   private var _update_date:String;
                   private var _vendor_related:Boolean;
                   public var isDirty:Boolean = false;
                   public function get vendor_related():Boolean
                        return _vendor_related;
                   public function set vendor_related(value:Boolean):void
                        _vendor_related = value;
                        isDirty = true;
                   public function get update_date():String
                        return _update_date;
                   public function set update_date(value:String):void
                        _update_date = value;
                        isDirty = true;
                   public function get insert_date():String
                        return _insert_date;
                   public function set insert_date(value:String):void
                        _insert_date = value;
                        isDirty = true;
                   public function get notes():String
                        return _notes;
                   public function set notes(value:String):void
                        _notes = value;
                        isDirty = true;
                   public function get description():String
                        return _description;
                   public function set description(value:String):void
                        _description = value;
                        isDirty = true;
                   public function get terminology():String
                        return _terminology;
                   public function set terminology(value:String):void
                        _terminology = value;
                        isDirty = true;
                   public function get id():Number
                        return _id;
                   public function set id(value:Number):void
                        _id = value;
                        isDirty = true;
    this is a very simple solution but it worked like a charm. Can somebody suggest me something else, a better solution?
    thank you
    r. Sandor
    P.S.: I didn't include the validators to simplify the example.

    hi,
    meanwhile I come a little bit further if you implement the isDirty flag into your remote model and let generate ( to be included in the flex model as well) a model with Flex you can listen to the propertyChange event and do implement a correctly functioning bindable property.
    public function VOMessageEntry():void
         addEventListener( PropertyChangeEvent.PROPERTY_CHANGE, handlePropertyChange );
    private function handlePropertyChange( event:PropertyChangeEvent ):void
         if ( event.property != "isDirty" )
              isDirty = true;
    this code must be inserted into the generated Object itself not in the _Super_objectname source code.
    I hope I could helped somebody with this solution.
    r. Sandor

  • Change log for Distribution model and partner profile

    Hello All,
    Could any one please suggest how to get teh change log of the distribution model and partner profiles in SAP.
    Thank you!
    Arvind

    Hello,
    The documentation says what distribution model is used for. My question is can we have change log for any change in the distribution model like user, time and date.
    In production system if distribution model and partner profiles are changed by someone to a destination which should not be used, then how can we trace who has changed it.
    I hope I am able to explain.
    Arvind

  • How can I change the cardinality of Model Node?

    Hi everybody
    How can I change the cardinality of Model Node?
    Previous:
    I import a Model RFC, and some nodes has the cardinality 0..1, but with this configuration, when I bind to the text fields of my webdynpro and deploy, all my fields text are unables when I shows the webdynpro.
    I check RFC and all the fields and estructures are obligatories.

    Hi Jesus,
    You cannot change the cardinality of the model node. All  the properties of the Model node are derived from the Model object.
    Your input fields are disabled because you are not creating your model object properly.
    You can import the example project TutWD_FlightList, which is available in c:\Program Files\SAP\IDE\IDE70\eclipse\examples.
    Import it in NWDS and you can see how to initialize model object properly.
    Thanks
    Prashant

  • Implementing Language Change in Portal for annoymous users

    Hi
    i want to implement Language change option in portal for annoymous users
    can anyone help me with the procedure i need to follow for implementing the change of language
    Regards
    JM

    Currently there are 2 ways to do this.
    1. with URL iViews
    These iViews have the "Language specific URLs"-Option. There you can specify which html file schould be displayed depending on the language.
    But this works only for html files.
    This would work fine together with the things i explained above.
    2.switch between different anonymous user
    This is a little bit tricky. You need an application, that is able to switch between different user. For example: Switching from user german to user english.
    In this case you would have to assign the language specific contents to these users.Here is a blog that describes how to implement this application.
    Blog Link
    I am working currently on this to get it running. So if you manage to do so, you could help me maybe.:)
    Regards,
    Marcus
    Message was edited by:
            Marcus Böhm

  • How to change URL of Webservice Model without reconfiguring or creating new

    Hi,
    I have create a WebService Model with DEV url (some Dev URL ) using
    Import WebService Model DEPRECATED option
    Now my application is moving to TEST and PROD.
    Is it possible to change DEV URL in webdynpro application application without reconfiguring MODEL or recreating new
    with TEST and PROD urls.
    Please help me

    Hi,
    You need to use adaptive webservice model to change the webservice URL based on the environment i.e. Dev,Test or production which is availiable in NWDS 2004s environment.
    You can refer to links mentioned in below forum.
    Re: Differnce between adptive web service model and webservice model(depricated
    if you you are using webservice model then you need to write the code to generate URL for end point dynamically based on the application environment.
    and then you need to set EndPoint of webservice model with that URL befroe execution of the model.
    e.g.
    String l_endpointurl ="http://"+ l_Server+ ":"+ l_port+ "/webservice name/Config1?style=document";
    l_modeloobject.modelObject()._setEndPoint(l_endpointurl);
    //if service is secured....
    l_modeloobject.modelObject()._setUser(l_userID);
    l_modeloobject.modelObject()._setPassword(l_pwd);
    l_modeloobject.modelObject().execute();
    Regards,
    Shruti.

  • Changing a JTable's model

    Hello everyone,
    I dont have a whole lot of experience w/ JTables and this problem has been troubling me for a while now. I have a JTable that significantly changes when the user hits the calculate button, so instead of going through the trouble of completely reformatting the table by adding/removing columns and table headers, I simple make a new model and set the table's model to the new one, and then call table.updateUI(). The problem is that my custom cell renderer that displays a down or up arrow depending on how the given column is sorted stops working. The sorter works properly and the table displays properly, but the arrows do not change from up to down or vise versa when a column is resorted. The whole process works just fine the first time, but the more times the user pushes the calculate button the more off it gets. I have added a flag in the actionPerformed method in my cell renderer that tells me when the table header is clicked. Every time the calculate button is hit, more flags appear when the table header is clicked. Therefore the arrows change position on odd numbers and do not on evens (because the evens cancel eachother out and the arrow appears to sit still), however the sorter still works properly. It seems as though somehow a new mouse listener or cell renderer is added after each time the calculate button is pressed. Either that or the entire table is not being reset somehow and something is still invisible in the background.
    Here is some of my code.
    // The initial table with no data
    String[] str = {"class 1", "class 2", "class 3", "class 4", "class 5", "= GPA"};
    String[][]  data= {{"", "", "", "", "", ""},
    pmModel = new ProjectionModel(str, data);
    mainTable = new JTable(pmModel);
    mainTable.getTableHeader().setDefaultRenderer(new SortButtonRenderer());
    // After the calculate button has been pushed:
    // The table is reset here. TableSorter extends TableMap
        ProjectionModel newModel = new ProjectionModel(courseList, charList);
        TableSorter sorter = new TableSorter(newModel);
        // this method is shown below
        sorter.addMouseListenerToHeaderInTable(mainTable);
        sorter.sortedUp = false;
        mainTable.addNotify();
        mainTable.setModel(sorter);
        // SortButtonRenderer extends TableCellRenderer
        SortButtonRenderer renderer = new SortButtonRenderer();
        mainTable.getTableHeader().setDefaultRenderer(renderer);
        // set the arrow to DOWN on the first column
        renderer.setSelectedColumn(0);
        renderer.setSelectedColumn(0);
        mainTable.updateUI();
    // This is the addMouseListenerToTable(JTable table) found in the TableSorter class
        public void addMouseListenerToHeaderInTable(JTable table) {
            final TableSorter sorter = this;
            final JTable tableView = table;
            tableView.setColumnSelectionAllowed(false);
            MouseAdapter listMouseListener = new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    TableColumnModel columnModel = tableView.getColumnModel();
                    int viewColumn = columnModel.getColumnIndexAtX(e.getX());
                    int column = tableView.convertColumnIndexToModel(viewColumn);
                    if (e.getClickCount() == 1 && column != -1) {
                      SortButtonRenderer renderer =
                            (SortButtonRenderer)tableView.getTableHeader().getDefaultRenderer();
                        //int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
                        //boolean ascending = (shiftPressed == 0);
                        boolean ascending = (renderer.getLastColumn() == column && !sortedUp);
                        renderer.setLastColumn(column);
                        sorter.sortByColumn(column, ascending);
                        if (ascending) sortedUp = true;
                        else sortedUp = false;
                        renderer.setSelectedColumn(column);
                        // the flag that prints the column that is pressed
                        System.out.println(column + " " + sortedUp);
            JTableHeader th = tableView.getTableHeader();
            th.addMouseListener(listMouseListener); // it seems like i need a way to remove any
    // previous mouseListeners here, i think this would solve the problem
        }The flag's output looks something like this:
    < first time calculate button is clicked >
    < column 0 is clicked> 0 false
    < column 0 is clicked again > 0 true
    < second time calculate button is clicked >
    < column 0 is clicked >
    0 false
    0 true
    notice they cancel eachother out so the arrow stays in the same position
    < third time calculate button is clicked >
    < column 0 is clicked >
    0 false
    0 true
    0 false
    notice they dont cancel eachother out, so the arrow changes positions
    This problem is really bugging me. I appreciate any help. Thanks.
    -kc

    Well I fixed my problem but I kind of cheated...
    I used a static variable in the class that inits the GUI to keep track of the MouseListeners that are added to the table headers by the TableSorter. In the TableSorter class's addMouseListenerToTableHeader(JTable table) class I added a line of code before the "th.addMouseListener(listListener)" line: "th.removeMouseListener(Projector.lastListener))"
    It works but it kind of sucks. If there is a better way to do it that would be great. I'm sorry if you read through all of that stuff and then I ended up fixing my own problem anyway :(
    Thanks anyway.
    -kc

  • Change Process Number when modeling DFD

    Hello everyone, I'm currently modeling a Data Flow Diagram for one of my classes. The requirement for the diagram is that each process must have a number like 1.0, 1.1, 1.2, etc. However, when I go to the properties for the process, I can see no way to change this. Every time I create a new process, it just goes 1, 2, 3, etc. So if I create a process out of step, I can't change the number. How do I do this? Thanks.

    Hello,
    use diagram dialog to reorder processes belonging to that diagram.
    Philip

  • Arc is not implemented for SQL Server 2005 physical model

    I added the Arc in my relational model, which is supposed to provide that references are mutually exclusive (so only one refering column can be not null). However there is not any implementation for this in the SQL Server 2005 physical model. The SQL code generated simply ignores the Arc and allows any values for the columns covered by Arc. If we check Oracle physical model. then it generates some trigger, which controls how many columns have values assigned - this is actually an implementation of Arc. But there is nothing of this kind for SQL Server model...
    By the way, implementing this Arc by trigger looks like to heavy approach. The very simple table level check constraint will do the same job. But this is a different subject though.
    Edited by: Otbl on Nov 3, 2011 7:34 PM

    Hi Dmitry,
    it's fixed in Data Modeler 3.1 EA2.
    Philip

  • Changing from full recovery model to simple in sql 2012 always on

    how do I change from a full recovery model to simple in an always on sql 2012 setup? When I try to change it it gave this error

    The physical size of the log file will not change unless you manually shrink the file.  A backup marks the log space as "reusable" internally.
    Please see:
    http://msdn.microsoft.com/en-us/library/ms365418.aspx

  • Solution ID 201056033 implemented but changes to signin.html still not seen

    Customer have implemented solution id 201056033 in WebLogic 9.2 MP3 patch 2 with PT 8.49.12.
    However, when they change signin.html for a web site the change is not seen. Browser cache has been purged.
    Yes, the web server were brought down and back up.
    Yes, the solution is implemented. It does not work as documented.
    Problem being:
    Able to change static HTML and have it seen by the user's
    browser. The web server is still caching the static HTML page even
    though the Solution ID says that doing what is documented in the
    solution will solve the problem.
    I need an answer to why the Solution ID is not working. I need
    to be able to change statuc HTML and have the web server serve it
    out to the browser.
    weblogic.xml has been updated as solution 201056033, that is to add
    '<resource-reload-check-secs>0</resource-reload-check-secs>':
    <container-descriptor>
    <servlet-reload-check-secs>-1</servlet-reload-check-secs>
    <session-monitoring-enabled>true</session-monitoring-enabled>
    <resource-reload-check-secs>0</resource-reload-check-secs>
    </container-descriptor>
    Implemented 201056033 . It does not solve the problem. Why does it not
    solve the problem?
    Any thoughts , pls help.
    Thanks

    It's not working because this change only causes the server side to reload the resource. The browser still has it cached, so it ignores it.
    What you have to do is send HTTP headers along with the response that convinces the browser not to cache the resource. One way to do this is to implement a servlet filter that injects the appropriate HTTP headers to cause this.
    The code for the class could look like this (I haven't declared it in a package, but you should):
    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletResponse;
    public class NoCachingFilter implements Filter
         private FilterConfig filterConfig = null;
         public void destroy()
              this.filterConfig = null;
         public void init(FilterConfig arg0) throws ServletException
              this.filterConfig = filterConfig;
         public void doFilter(ServletRequest request,
                                  ServletResponse response,
                                  FilterChain chain)
         throws IOException, ServletException
         HttpServletResponse httpResponse = (HttpServletResponse) response;
         httpResponse.setHeader("Cache-Control", "no-cache");
         httpResponse.setDateHeader("Expires", 0);
         httpResponse.setHeader("Pragma", "No-cache");
         chain.doFilter(request, response);
    You would declare this filter in your web.xml like this:
    <filter>
    <filter-name>No Caching Filter</filter-name>
    <filter-class>carousel.NoCachingFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>No Caching Filter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    --------------------------

  • Implement QBE case insensitive search using model layer?

    Using ADF 11.1.1.6.2
    We know we can set filterFeatures='caseInsensitive' at UI layer to make QBE to search case insensitive.
    How can we push that behavior using model layer implementation?
    Thanks

    Using ADF 11.1.1.6.2
    We know we can set filterFeatures='caseInsensitive' at UI layer to make QBE to search case insensitive.
    How can we push that behavior using model layer implementation?
    Thanks

  • Howto implement hand-rolled locking with SQL?

    Hi there,
    For now I used java.util.Concurrent's classes for locking critical sections which should only be modified/read by a client at a time. However now one customer would like to cluster our app and I wonder wether the locking could also be done with SQL.
    The reason why we don't use some high-level SQL constructs is that our product only uses a really very small subset of SQL.
    Any ideas wether/how double-checked locking could be implemented using SQL?
    Thank you in advance, lg Clemens

    Here is a link to a nice discussion on your topic.
    It might or might not help, but it did appear
    pertinent to your questions by talking about
    alternative methods and pros and cons of
    auto-incrementing.Ooooh are we back on this topic again? Delightful. And just in time for the holiday when I shall have the time to compose lengthy replies on the subject.
    Since the last time this subject came up (and I recall having some discussion with duffymo about it) I have been doing further thinking about it all and here are my thoughts.
    Design Stage
    A bit of a rehash of what I said before. I think it is key during the database (note database and not application) design phase to design without using auto-generated keys. Your database integrity, that is the integrity of each table and the integrity of each relationship between tables must be able to "stand up" without the use of these keys.
    In general proper database design is, I believe, a learned craft. Since the amount of poor designs, at least what I come across, seems so prolific I think a good rule of thumb would be to apply the above rule to one's design stringently as a good practice that will create proper designs.
    Creation and Deployment Phase
    When you have a solid design then before creating and deploying the database design is a good time to look at where generated keys might be appropriate. Generally speaking I recommend using them for the following reasons
    1) Ease of development. Let's face it joining key to key on an numeric column is much easier than joining on multiple variable columns.
    2) Performance. The time to access a multiple key field with variable length columns is going to be different than a single key numeric field. Now this item was refuted in the article WorkForFood linked above but I think there is an issue to consider here all the same. It all depends on the usage.
    I will certainly give you that database indexes are wonderful things and in most cases the performance differences between searching by a multiple column key vs a single column key are going to be hardly measurable. But what about updating? And what about the size of your table.
    If the database is small or the database is largely for analysis and reporting then performance is (probably) not going to be an issue. However for a large scale transaction database I think one would be foolish to dismiss the performance impact out of hand.
    3) Long-term flexibility. This was a point raised by duffymo in the last go around and it's certainly worth considering. The general theory is this, when you use non-generated keys you are locking business logic into your database design. If you need to make changes later for business reasons you are up the proverbial creek.
    Personally, while I think the point is valid I am not overly sold on this one. I think there is only so much "planning against future changes" that one can and should do. I would rather see the needs of the current design met in an effective fashion before considering this. So I guess to me if all other things are equal this a reason to use generated keys.
    Rules for Using Generated Keys
    The two rules I would like to see people use when using generated keys are as follows.
    1) Always create a constraint on the real key. Again and again I encounter systems where this has not been done. You might as well not have any keys at all with this kind of disaster. If you can't create a constraint then I think you have to go back to the design stage and rethink this.
    2) Never use generated keys when one or more foreign keys form part of the primary key. Really this advice applies exclusively to tables that form many-to-many relationships. Auto-generated keys should never ever be used in tables like this. It's just a mess waiting to happen.
    Of course the key could be several foreign keys that are each auto-generated keys in their own tables...
    Other stuff I am going to refute in the linked article that doesn't fit anywhere else
    Well mainly I don't like the concept of application generated keys. Which is discussed in some of the replies. To me that is a mix of all the cons of using generated keys and the cons of using natural keys all at the same time while adding a new level of stuff tied into your application logic that will make life more difficult in the end. I just don't like it.

  • How to configure/implement stateful r3 connection in Arfc2 model?

    Hi,
    After migration to Arfc2 model rfc function executed in different r/3 session.
    How to configure/implement stateful behavior as arfc1 for using abap enqueue, transaction, shared between fm global variables from function group?
    Wbr, Ivan

    Hi,
    thanks for your reply, but I'm afraid your post does not answer my question.
    I don't have an issue concerning the state of the Web Dynpro Application - my problem is, that if I use ARFC2 (and not its predecessor ARFC1) to call an ABAP backend, every call to a function in this backend results in an independent session and this way doesn't share the same space in memory.
    Indeed, you need less RFC connections this way, and this is an important advantage, but in some cases you have to redesign and rewrite substantial parts of an application if it was designed under aspects of ARFC1.
    And I'm now looking for a way to have ARFC1-like behaviour with ARFC2.
    Greets
    Bernd

  • Changing administrative user name - Model WRT31ON

    We can't seem to find how to change the administrative username from blank to a actual name.
    Is this able to be done on this model?
    Thanks,
    Charlie

    No. Linksys only uses the password. And it wouldn't be more secure if there was a user name...

Maybe you are looking for