View Javadoc
1   /*
2    * $Source$
3    * $Revision$
4    *
5    * Copyright (C) 2007 Tim Pizey
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     Tim Pizey <timp At paneris.org>
42   *     http://paneris.org/~timp
43   */
44  package org.melati.admin;
45  
46  import java.util.Enumeration;
47  
48  import org.melati.LogicalDatabase;
49  import org.melati.Melati;
50  import org.melati.poem.Database;
51  import org.melati.poem.Field;
52  import org.melati.poem.Persistent;
53  import org.melati.poem.PoemTask;
54  import org.melati.poem.PoemThread;
55  import org.melati.poem.Table;
56  import org.melati.poem.util.MappedEnumeration;
57  import org.melati.servlet.PathInfoException;
58  import org.melati.servlet.TemplateServlet;
59  import org.melati.template.ServletTemplateContext;
60  
61  /**
62   * 
63   * Copy one db to another.
64   * 
65   * @author timp
66   * @since 3 Oct 2007
67   *
68   */
69  public class Copy extends TemplateServlet {
70  
71    private static final long serialVersionUID = -3659643334509606759L;
72    static Database fromDb = null;
73    static Database toDb = null;
74    
75    
76    /** 
77     * {@inheritDoc}
78     * @see org.melati.servlet.TemplateServlet#prePoemSession(org.melati.Melati)
79     */
80    protected void prePoemSession(Melati melati) throws Exception {
81      super.prePoemSession(melati);
82      String[] parts = melati.getPathInfoParts();
83      if (parts.length != 2)
84        throw new PathInfoException(melati.getRequest().getPathInfo(),
85            new RuntimeException("Two database names expected"));
86      String fromDbName = parts[0];
87      String toDbName = parts[1];
88  
89      copy(fromDbName, toDbName);
90      
91    }
92    
93    /** 
94     * {@inheritDoc}
95     * @see org.melati.servlet.TemplateServlet#doTemplateRequest
96     */
97    protected String doTemplateRequest(Melati melati,
98            ServletTemplateContext templateContext) throws Exception {
99      melati.setPassbackExceptionHandling();
100     melati.setResponseContentType("text/html");
101     templateContext.put("admin", new AdminUtils(melati));
102 
103     String[] parts = melati.getPathInfoParts();
104     String fromDbName = parts[0];
105     String toDbName = parts[1];
106 
107     templateContext.put("fromDbName",fromDbName);
108     templateContext.put("toDbName",toDbName);
109     return "org/melati/admin/CopyDone";
110   }
111 
112   /**
113    * @param from
114    * @param to
115    * @return the updated db
116    */
117   public static Database copy(String from, String to) { 
118     fromDb = LogicalDatabase.getDatabase(from);
119     toDb =  LogicalDatabase.getDatabase(to);
120     return copy();
121   }
122   /**
123    * @return the updated db
124    */
125   public static Database copy(Database fromDbIn, final Database toDbIn) {
126     fromDb = fromDbIn;
127     toDb = toDbIn;
128     return copy();
129   }
130   /**
131    * @return the updated db
132    */
133   public static Database copy() { 
134     if (fromDb.getClass() != toDb.getClass()) 
135       throw new AnticipatedException("Both from(" + fromDb.getClass() + ") and " + 
136                                      "to(" + toDb.getClass() + ") databases " + 
137                                      "must be of the same class");
138     if (fromDb == toDb) 
139       throw new AnticipatedException("A database cannot be copied onto itself");
140     toDb.inSessionAsRoot( 
141           new PoemTask() {
142             public void run() {
143               System.err.println("PoemThread " + PoemThread.database().getDisplayName());
144                 Enumeration<Table<?>> en = fromDb.displayTables(null);
145                 while(en.hasMoreElements()) { 
146                   Table<?> fromTable = en.nextElement();
147                   String fromTableName = fromTable.getName();
148                   System.err.println("From " + fromDb + " table " + fromTableName); 
149                   Table<?> toTable = toDb.getTable(fromTableName);
150                   int count = toTable.count();
151                   if (count != 0 ) {
152                     System.err.println("Skipping " + toTable.getName() + " as it contains " + count + " records." );
153                   } else { 
154                     System.err.println(toTable.getName() + " in both and empty in destination.");
155                     Enumeration<Persistent> recs = objectsFromTroids(
156                             fromTable.troidSelection((String)null, 
157                                                      (String)null, false, null), 
158                                                      fromTable);
159                     while (recs.hasMoreElements()) {
160                       Persistent p = (Persistent)recs.nextElement();
161                       Persistent p2 = toTable.newPersistent();
162                       Enumeration<Field<?>> fields = p.getFields();
163                       while (fields.hasMoreElements()) { 
164                         Field<?> f = fields.nextElement();
165                         p2.setRaw(f.getName(), f.getRaw());
166                       }
167                       p2.makePersistent();
168                       System.err.println("Created:" + p2.displayString());
169                     }
170                   }
171                 }
172               }
173             });
174     return toDb;
175 
176   }
177   static Enumeration<Persistent> objectsFromTroids(Enumeration<Integer> troids, final Table<?> t) {
178     return new MappedEnumeration<Persistent, Integer>(troids) {
179         public Persistent mapped(Integer troid) {
180           return t.getObject(troid);
181         }
182       };
183   }
184 
185 }