Coverage Report - org.jtheque.core.managers.patch.PatchManager
 
Classes in this File Line Coverage Branch Coverage Complexity
PatchManager
0 %
0/121
0 %
0/40
2.2
 
 1  
 package org.jtheque.core.managers.patch;
 2  
 
 3  
 /*
 4  
  * This file is part of JTheque.
 5  
  *
 6  
  * JTheque is free software: you can redistribute it and/or modify
 7  
  * it under the terms of the GNU General Public License as published by
 8  
  * the Free Software Foundation, either version 3 of the License.
 9  
  *
 10  
  * JTheque is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  
  * GNU General Public License for more details.
 14  
  *
 15  
  * You should have received a copy of the GNU General Public License
 16  
  * along with JTheque.  If not, see <http://www.gnu.org/licenses/>.
 17  
  */
 18  
 
 19  
 import org.jtheque.core.managers.ManagerException;
 20  
 import org.jtheque.core.managers.Managers;
 21  
 import org.jtheque.core.managers.log.ILoggingManager;
 22  
 import org.jtheque.core.managers.view.able.IViewManager;
 23  
 import org.jtheque.core.utils.file.XMLException;
 24  
 import org.jtheque.core.utils.file.XMLReader;
 25  
 import org.jtheque.core.utils.file.XMLWriter;
 26  
 import org.jtheque.utils.bean.IntDate;
 27  
 import org.jtheque.utils.io.FileUtils;
 28  
 
 29  
 import java.io.File;
 30  
 import java.util.ArrayList;
 31  
 import java.util.Collection;
 32  
 
 33  
 /**
 34  
  * A manager for the patch.
 35  
  *
 36  
  * @author Baptiste Wicht
 37  
  */
 38  
 public final class PatchManager implements IPatchManager {
 39  
     private final Collection<AppliedPatch> appliedPatches;
 40  
     private final Collection<OnlinePatch> onlinePatches;
 41  
     private final Collection<Patch> patches;
 42  
 
 43  
     private boolean updated;
 44  0
     private boolean xmlUpToDate = true;
 45  
 
 46  
     private static final int RESTART_CODE = 2;
 47  
 
 48  
     /**
 49  
      * Construct a new PatchManager.
 50  
      */
 51  
     public PatchManager() {
 52  0
         super();
 53  
 
 54  0
         patches = new ArrayList<Patch>(10);
 55  0
         appliedPatches = new ArrayList<AppliedPatch>(10);
 56  0
         onlinePatches = new ArrayList<OnlinePatch>(10);
 57  0
     }
 58  
 
 59  
     @Override
 60  
     public boolean isApplied(String name) {
 61  0
         boolean applied = false;
 62  
 
 63  0
         for (AppliedPatch patch : appliedPatches) {
 64  0
             if (patch.getName().equals(name)) {
 65  0
                 applied = true;
 66  
             }
 67  
         }
 68  
 
 69  0
         return applied;
 70  
     }
 71  
 
 72  
     @Override
 73  
     public void setUpdated(boolean updatedParameter) {
 74  0
         updated = updatedParameter;
 75  0
         xmlUpToDate = false;
 76  0
     }
 77  
 
 78  
     @Override
 79  
     public void preInit() {
 80  0
         boolean restart = applyPatchesIfNeeded();
 81  
 
 82  0
         if (restart) {
 83  0
             Managers.getManager(IViewManager.class).getSplashManager().closeSplashScreen();
 84  
 
 85  0
             Managers.getCore().getLifeCycleManager().restart();
 86  
         }
 87  0
     }
 88  
 
 89  
     @Override
 90  
     public void init() throws ManagerException {
 91  0
         File f = new File(Managers.getCore().getFolders().getApplicationFolder(), "/core/patchs.xml");
 92  
 
 93  0
         if (f.exists()) {
 94  0
             openConfiguration(f);
 95  
         } else {
 96  0
             updated = true;
 97  0
             xmlUpToDate = false;
 98  
         }
 99  0
     }
 100  
 
 101  
     /**
 102  
      * Open the configuration file of the patches.
 103  
      *
 104  
      * @param f The configuration File.
 105  
      */
 106  
     private void openConfiguration(File f) {
 107  0
         XMLReader reader = new XMLReader();
 108  
 
 109  
         try {
 110  0
             reader.openFile(f);
 111  
 
 112  0
             readUpdated(reader);
 113  0
             readAppliedPatches(reader);
 114  0
             readPatches(reader);
 115  0
         } catch (XMLException e) {
 116  0
             Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e);
 117  
         } finally {
 118  0
             FileUtils.close(reader);
 119  0
         }
 120  0
     }
 121  
 
 122  
     /**
 123  
      * Read the updated value of the configuration.
 124  
      *
 125  
      * @param reader The reader to use.
 126  
      * @throws XMLException if an exception occurs during the XML reading process.
 127  
      */
 128  
     private void readUpdated(XMLReader reader) throws XMLException {
 129  0
         String strUpdated = reader.readString("updated", reader.getRootElement());
 130  
 
 131  0
         if (strUpdated != null && "1".equals(strUpdated)) {
 132  0
             updated = true;
 133  
         }
 134  0
     }
 135  
 
 136  
     /**
 137  
      * Read the patches.
 138  
      *
 139  
      * @param reader The reader to use.
 140  
      * @throws XMLException if an exception occurs during the XML reading process.
 141  
      */
 142  
     private void readPatches(XMLReader reader) throws XMLException {
 143  0
         for (Object currentNode : reader.getNodes("patch/patch", reader.getRootElement())) {
 144  0
             String c = reader.readString("@class", currentNode);
 145  
 
 146  
             try {
 147  0
                 Class<?> patchClass = Class.forName(c, true, getClass().getClassLoader());
 148  
 
 149  0
                 if (Patch.class.isAssignableFrom(patchClass)) {
 150  0
                     Class<Patch> castedClass = (Class<Patch>) patchClass;
 151  
 
 152  
                     try {
 153  0
                         patches.add(castedClass.newInstance());
 154  0
                     } catch (InstantiationException e) {
 155  0
                         Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e);
 156  0
                     } catch (IllegalAccessException e) {
 157  0
                         Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e);
 158  0
                     }
 159  
                 }
 160  0
             } catch (ClassNotFoundException e) {
 161  0
                 Managers.getManager(ILoggingManager.class).getLogger(getClass()).error(e);
 162  0
             }
 163  0
         }
 164  0
     }
 165  
 
 166  
     /**
 167  
      * Read the applied patches.
 168  
      *
 169  
      * @param reader The reader to use.
 170  
      * @throws XMLException if an exception occurs during the XML reading process.
 171  
      */
 172  
     private void readAppliedPatches(XMLReader reader) throws XMLException {
 173  0
         for (Object currentNode : reader.getNodes("applied/patch", reader.getRootElement())) {
 174  0
             AppliedPatch patch = new AppliedPatch();
 175  
 
 176  0
             patch.setDate(new IntDate(reader.readInt("date", currentNode)));
 177  0
             patch.setName(reader.readString("name", currentNode));
 178  
 
 179  0
             appliedPatches.add(patch);
 180  0
         }
 181  0
     }
 182  
 
 183  
     @Override
 184  
     public void close() {
 185  0
         if (!xmlUpToDate) {
 186  0
             saveXML();
 187  
         }
 188  0
     }
 189  
 
 190  
     /**
 191  
      * Save the XML of patches.
 192  
      */
 193  
     private void saveXML() {
 194  0
         XMLWriter writer = new XMLWriter("config");
 195  
 
 196  0
         writer.setCurrent(writer.getRoot());
 197  
 
 198  0
         saveUpdated(writer);
 199  0
         saveAppliedPatches(writer);
 200  0
         savePatches(writer);
 201  
 
 202  0
         writer.write(Managers.getCore().getFolders().getApplicationFolder().getAbsolutePath() + "/core/patchs.xml");
 203  0
     }
 204  
 
 205  
     /**
 206  
      * Save the patches to the writer.
 207  
      *
 208  
      * @param writer The writer to use.
 209  
      */
 210  
     private void savePatches(XMLWriter writer) {
 211  0
         writer.add("patchs");
 212  
 
 213  0
         for (OnlinePatch patch : onlinePatches) {
 214  0
             writer.add("patch");
 215  0
             writer.addAttribute("class", patch.getClassName());
 216  0
             writer.switchToParent();
 217  
         }
 218  
 
 219  0
         writer.switchToParent();
 220  0
     }
 221  
 
 222  
     /**
 223  
      * Save the applied patches.
 224  
      *
 225  
      * @param writer The writer to use.
 226  
      */
 227  
     private void saveAppliedPatches(XMLWriter writer) {
 228  0
         writer.add("applied");
 229  
 
 230  0
         for (AppliedPatch patch : appliedPatches) {
 231  0
             writer.add("patch");
 232  
 
 233  0
             writer.addOnly("date", Integer.toString(patch.getDate().intValue()));
 234  0
             writer.addOnly("name", patch.getName());
 235  
 
 236  0
             writer.switchToParent();
 237  
         }
 238  
 
 239  0
         writer.switchToParent();
 240  0
     }
 241  
 
 242  
     /**
 243  
      * Save the updated flag.
 244  
      *
 245  
      * @param writer The writer to use.
 246  
      */
 247  
     private void saveUpdated(XMLWriter writer) {
 248  0
         if (updated) {
 249  0
             writer.addOnly("updated", "1");
 250  
         } else {
 251  0
             writer.addOnly("updated", "0");
 252  
         }
 253  0
     }
 254  
 
 255  
     /**
 256  
      * Add an applied patch.
 257  
      *
 258  
      * @param patch The patch.
 259  
      */
 260  
     private void addAppliedPatch(AppliedPatch patch) {
 261  0
         appliedPatches.add(patch);
 262  0
         xmlUpToDate = false;
 263  0
     }
 264  
 
 265  
     @Override
 266  
     public void registerPatch(Patch p) {
 267  0
         patches.add(p);
 268  0
     }
 269  
 
 270  
     @Override
 271  
     public boolean applyPatchesIfNeeded() {
 272  0
         boolean restart = false;
 273  
 
 274  0
         if (updated) {
 275  0
             if (applyAllNeededPatches()) {
 276  0
                 restart = true;
 277  
             } else {
 278  0
                 setUpdated(false);
 279  0
                 restart = false;
 280  
             }
 281  
         }
 282  
 
 283  0
         return restart;
 284  
     }
 285  
 
 286  
     /**
 287  
      * Apply all the needed patches.
 288  
      *
 289  
      * @return true if we must restart else false.
 290  
      */
 291  
     private boolean applyAllNeededPatches() {
 292  0
         boolean restart = false;
 293  
 
 294  0
         for (Patch patch : patches) {
 295  0
             if (!isApplied(patch.getName()) && patch.mustBeAppliedFor(Managers.getCore().getApplication().getVersion())) {
 296  0
                 int code = patch.apply();
 297  
 
 298  0
                 if (code < 0) {
 299  0
                     registerAppliedPatch(patch);
 300  
                 }
 301  
 
 302  0
                 if (code == RESTART_CODE) {//Restart
 303  0
                     restart = true;
 304  0
                     break;
 305  
                 }
 306  0
             }
 307  
         }
 308  
 
 309  0
         return restart;
 310  
     }
 311  
 
 312  
     /**
 313  
      * Register an applied patch.
 314  
      *
 315  
      * @param patch The patch that has been applied.
 316  
      */
 317  
     private void registerAppliedPatch(Patch patch) {
 318  0
         AppliedPatch applied = new AppliedPatch();
 319  0
         applied.setDate(IntDate.today());
 320  0
         applied.setName(patch.getName());
 321  
 
 322  0
         addAppliedPatch(applied);
 323  0
     }
 324  
 
 325  
     @Override
 326  
     public void registerOnlinePatch(OnlinePatch patch) {
 327  0
         onlinePatches.add(patch);
 328  0
     }
 329  
 }