/* * mainLoader.java * * Created on 30. Juni 2000, 10:15 */ package AdmSoftware.App; import AdmSoftware.App.grid.CallFormGridCommand; import AdmSoftware.App.grid.CloneContactCommand; import AdmSoftware.App.grid.CreateContactCommand; import AdmSoftware.App.grid.PingGridCommand; import AdmSoftware.App.grid.SyncSubGridCommand; import AdmSoftware.App.grid.UpdateContactCommand; import AdmSoftware.utils.AppUtils; import de.sepix.sys.grid.CallServer; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import javax.swing.*; import java.awt.*; import sys.*; import sys.filesys.JFileSecureChooser; import sys.utils.ClassLoaderExtender; import java.util.StringTokenizer; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.Arrays; /** * Startet die Anwendung. * @author Aljoscha Rittner. * @version */ public class mainLoader { protected static FormularItem fi; protected static boolean splashIsVisible = false; protected static boolean readySplash = false; protected static boolean breakSplash = false; private static ThreadLocal stamp = new ThreadLocal () { protected synchronized Object initialValue() { return new SimpleDateFormat ("yyyyMMddHHmmssS"); } }; /** * Dicht machen. */ private mainLoader () {} public static class SplashWindow extends Frame { private Image imageLogo; private Image image; private String updateVersion = Pool.getProperty ("Update.Version", "0"); //NOI18N public SplashWindow (String specialImageName, String defaultImageName, String logoName) { super (); setUndecorated(true); setSize (400, 261); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension dialogSize = getSize(); setLocation((screenSize.width-dialogSize.width)/2, (screenSize.height-dialogSize.height)/2); setBackground (Color.black); try { ImageResource ir = new ImageResource (specialImageName); image = ir.getImage (); } catch (java.io.IOException ioe) { try { ImageResource ir = new ImageResource (defaultImageName); image = ir.getImage (); ImageResource irLogo = new ImageResource (logoName); imageLogo = irLogo.getImage (); } catch (java.io.IOException ioe2) { System.out.println("Kann Splash-Grafiken nicht laden... " + ioe2); } } if ( image != null ) { MediaTracker md = new MediaTracker (SplashWindow.this); try { md.addImage (image, 0); if ( imageLogo != null ) md.addImage (imageLogo, 1); md.waitForID (0); if ( imageLogo != null ) md.waitForID (1); } catch ( InterruptedException ie ) {;} BufferedImage buf = new BufferedImage (image.getWidth (null), image.getHeight (null), BufferedImage.TYPE_INT_RGB); Graphics gImage = buf.getGraphics (); gImage.drawImage (image, 0, 0, null); if ( gImage != null ) { if ( imageLogo != null ) { gImage.drawImage (imageLogo, 255, 200, null); } String javaVersion = System.getProperty("java.runtime.version"); gImage.setColor (Color.darkGray); if ( !updateVersion.equals ("0") ) { //NOI18N gImage.drawString ("u-" + updateVersion + " JRE: " + javaVersion, 50, 163); //NOI18N } else { gImage.drawString ("JRE: " + javaVersion, 50, 163); //NOI18N } } image = buf; } this.repaint (); // setLayout (new BoxLayout(splash.getContentPane (), BoxLayout.Y_AXIS)); } public void update (Graphics g) { paint (g); } public void paint (Graphics g) { if ( image != null ) { g.drawImage (image, 0, 0, null); } else { g.setColor (Color.white); g.drawString ("Sepix Sales System wird geladen...", 20, 100); } } } public static class Loader extends Thread { private SplashWindow splashWindow; public Loader () { super(); } public Loader (SplashWindow window) { super(); splashWindow = window; } private void openSplash () { if ( splashWindow == null ) { splashWindow = new SplashWindow ( "./AdmSoftware/icons/splashBusy.gif", //NOI18N "./AdmSoftware/icons/splash.gif", //NOI18N "./AdmSoftware/icons/btn_logo.gif"); //NOI18N } splashWindow.show(); } public void closeSplash() { SwingUtilities.invokeLater(new Runnable() { public void run () { if ( splashWindow != null ) { splashWindow.hide (); splashWindow.dispose (); splashWindow = null; } } }); } public void run() { SwingUtilities.invokeLater(new Runnable() { public void run () { openSplash(); } }); } } public static synchronized void setMain (FormularItem fi) { mainLoader.fi = fi; } public static synchronized FormularItem getMain () { return mainLoader.fi; } /** * Direkt für die Kommandozeile geschrieben. */ public static void main(java.lang.String[] args) { if ( args.length > 0 && args[0].equals("-?") ) { JOptionPane.showMessageDialog(null, "Parameter:\nopen AdmSoftware.App.jFrm(Name)\nopen-nolock AdmSoftware.App.jFrm(Name)"); System.exit(0); } sys.utils.Utils.loadClasses(); de.sepix.sys.dbo.utils.DBConfig.setConfiguration(Pool.getProperties()); Pool.loadProperties (); try { Pool.writeLogFile ("[START] Startup folder is " + Pool.getPathRelative (false)); } catch ( IOException ioe ) { Pool.error (ioe, "[START] Startup folder is not valid"); } final long MB = (1024L*1024L); long VRAM_TEST = Pool.getPropertyByteSize ("System.TestDriveSpace.MinimumDiskspace", 100L * 1024L * 1024L); //NOI18N if ( !Pool.isEnoughVRamForStartup() ) { long mb = VRAM_TEST / MB; Pool.showError ("Es wird üblicherweise das Laufwerk getestet, auf dem die Applikation\n" + "gestartet wurde und das Laufwerk, auf dem die Datenbank gespeichert ist.\n" + "Sollte die Datenbank nicht lokal auf dem Rechner sein, wird keine Prüfung\n" + "für die Datenbank durchgeführt.\n" + "Die Prüfungen können über die Parameter\n" + " System.TestDriveSpace=true|false\n" + " System.TestDriveSpace.MinimumDiskspace=100 Mb\n" + " System.TestDriveSpace.DB=true|false\n" + "gesteuert. Das Laufwerk der Datenbank wird über den Eintrag DSN ermittelt.", "

Freier Festplattenspeicher reicht nicht aus

" + "Für einen stabilen Programmlauf muß mindestens " + mb + "MB Speicher auf der Festplatte zur Verfügung stehen.

" + "Sie sollten umgehend mehr Speicherplatz zur Verfügung stellen!
" + "" + "Zu geringer freier Festplattenspeicher zerstört die S³-Datenbank
" + "und verursacht ggf. mehrtägige Reparaturarbeiten und Datenverlust." + "


" + "Bei Fragen wenden Sie sich bitte an die IT-Abteilung.", null , true); } // Sofort APP-Update: boolean toBack = false; boolean appFailed = false; if ( getAppUpdateFiles().length > 0 ) { if ( !appUpdate() ) { toBack = true; appFailed = true; } } String specialLogo = Pool.getProperty ("Logo.Splash.Special", "./AdmSoftware/icons/splashBusy.gif"); //NOI18N String standardLogo = Pool.getProperty ("Logo.Splash.Standard", "./AdmSoftware/icons/splash.gif"); //NOI18N String customerLogo = Pool.getProperty ("Logo.Splash.Customer", "./AdmSoftware/icons/btn_logo.gif"); //NOI18N Pool.getFormularManager(); boolean noLock = args.length > 0 && args[0].endsWith ("-nolock"); if ( !noLock ) { if ( Pool.isInstanceRunningLock() ) { Pool.showError("Die Anwendung ist bereits gestartet. Bitte beenden Sie erst die laufende Anwendung"); System.exit(4); return; } else { if ( !Pool.setInstanceRunningLock() ) { Pool.showError("Die Anwendung ist bereits gestartet. Bitte beenden Sie erst die laufende Anwendung"); System.exit(4); return; } } } Calendar cal = Pool.getNow (); if ( cal.get (Calendar.YEAR) < 2005 ) { String msg = "Laut Ihrem Computer ist Heute

{0}

" + "Dies scheint ein Datum in der Vergangenheit zu sein. " + "Bitte überprüfen Sie, ob das das Datum korrekt ist.
" + "Wenn das Datum nicht stimmt, beenden Sie die Anwendung und korrigieren Sie das Datum." ; String date = DateFormat.getDateInstance(DateFormat.FULL).format (cal.getTime()); Pool.showError (null, "Datumsfehler?", MessageFormat.format (msg, new Object[] {date}), true); } Loader loader = null; if ( Pool.getPropertyInternal ("GUI.NoSplash", "false").equals ("false") ) { // Hier noch nicht fertig: readySplash = false; // SplashLoader starten: loader = new Loader(new SplashWindow (specialLogo, standardLogo, customerLogo)); // loader.start(); loader.run(); } Pool.writeLogFile ("[CLASSLOADER] added archives: " + ClassLoaderExtender.buildCPDump (ClassLoaderExtender.getAddedJars())); Pool.writeLogFile ("[CLASSLOADER] added libraries: " + ClassLoaderExtender.buildCPDump (ClassLoaderExtender.getAddedLibs())); // Pool.redirectErr(); // nebenbei Hauptapplikation booten: boolean dbFailed = false; if ( sys.utils.UpdUtils.getDBUpdateFiles().length > 0 ) { if ( !sys.utils.UpdUtils.dbUpdate() ) { toBack = true; dbFailed = true; } else { AppUtils.clearLookUp (); } } if ( dbFailed || appFailed ) { Pool.showError( "Fehlgeschlagene Update-Dateien: " + sys.utils.UpdUtils.getFailedUpdateFiles(), "Fehler bei: " + (dbFailed ? "Datenbank-Update" : "") + " " + (appFailed ? "Applikations-Update" : ""), "Es wurde versucht ein Update für die Anwendung auszuführen.\nDieses Update ist fehlgeschlagen.\n\n" + "Bitte informieren Sie umgehend darüber per eService-Mail, weil die Anwendung ggf. nicht ordnungsgemäß ausgeführt werden kann.", true); } Pool.getLuCache (); Pool.getNumKreis (); Pool.loadHistoryKeyCache (); boolean noMain = false; if ( args != null && args.length > 1 ) { if ( args[0].startsWith ("open") ) { FormularParameters fp = new FormularParameters ("OSRUN"); fp.setParameter("ARGS", args); Pool.getFormularManager ().open (null, args[1], fp); noMain = true; } } if (!noMain) { SwingUtilities.invokeLater(new Runnable() { public void run() { setMain (Pool.getFormularManager ().open (null, "AdmSoftware.App.jFrmMain", null)); //NOI18N } }); } if ( loader != null ) { loader.closeSplash(); } // Da SplashScreen noch etwas länger da ist, möchte ich es auch sehen: // getMain().toBack(); // Den Formular-Cache füllen. String preCache = Pool.getPropertyInternal ("GUI.FormCache.Preload", ""); //NOI18N StringTokenizer st = new StringTokenizer (preCache, ",; "); // NOI18N while ( st.hasMoreTokens () ) { Pool.getFormularManager ().openCached (st.nextToken ()); } // Nu bin ich fertig readySplash = true; if (!noMain ) { if ( toBack ) { // Weil Fehler, dürfen die Meldungsmasken nicht verdeckt werden SwingUtilities.invokeLater(new Runnable() { public void run() { getMain().toBack(); } }); } if ( Pool.getPropertyBool("Modules.Grid.CallServer", false) ) { CallServer server = CallServer.startServer(); server.registerCommand (new CloneContactCommand()); server.registerCommand (new CreateContactCommand()); server.registerCommand (new UpdateContactCommand()); server.registerCommand (new SyncSubGridCommand()); server.registerCommand (new PingGridCommand()); server.registerCommand (new CallFormGridCommand()); } } } /** * Ermittelt Update-Dateien, die nur während des Laufes von S³ abgearbeitet * werden können und sollen. * Das sind appupd*.bat-Dateien und die start.jar-Datei. * @return Eine Liste von Dateien, die als Update laufen sollen. */ public static File[] getAppUpdateFiles() { try { File[] scripts = new File (Pool.getPathRelative (false), "updates/incoming/").listFiles(new FileFilter () { public boolean accept(File file) { if ( file.isDirectory() ) return false; String name = file.getName().toLowerCase(); return (name.startsWith("appupd") && name.endsWith(".bat")) || name.equalsIgnoreCase ("start.jar"); } }); if ( scripts != null ) { Arrays.sort(scripts); return scripts; } return new File[0]; } catch ( IOException ioe ) { return new File[0]; } } /** * Sucht im Hauptverzeichnis nach einem SQL-Script und führt * es aus. * Die Scripte tragen den Namen dbupd-jjjjMMtt.sql oder * dbupd-jjjjMMtt-id.sql (wenn mehr als ein Script benötigt wird). *

* Wenn sie abgearbeitet wurden, bekommen sie eine neue Endung. Entweder * .sqlok oder .sqlfail. */ public static boolean appUpdate () { boolean ok = true; File[] scripts = getAppUpdateFiles(); for ( int i = 0; i < scripts.length; i++ ) { ok = ok && appUpdate (scripts[i].getName()); } return ok; } public static boolean appUpdate (String fileName) { if ( fileName == null ) return false; if ( fileName.equalsIgnoreCase ("start.jar") ) { // Die start.jar Datei kann nur beim Lauf von S³ kopiert werden, weil // beim Start von S³ ja die start.jar-Datei als Launcher in Verwendung // ist. return appUpdateStart (new File (fileName), "s3"); } else { String exec = "cmd.exe /c " + fileName; try { Process p = Runtime.getRuntime ().exec (exec); int i = 0; try { i = p.waitFor (); new File (fileName).renameTo(new File (fileName + "ok")); } catch ( InterruptedException ie ) { Pool.error (ie, "[APPUpdate] Error on " + fileName); new File (fileName).renameTo(new File (fileName + "fail")); } finally { Pool.writeLogFile ("[APPUpdate] " + fileName + " returns " + i); } return true; } catch ( IOException ioe ) { Pool.error (ioe, "[APPUpdate] " + fileName + " returns an exception"); new File (fileName).renameTo(new File (fileName + "fail")); } return false; } } /** * Benennt eine Datei in einen eindeutigen Namen mit der Endung ".old" um. * @param destFile Datei die umbenannt werden soll. */ private static boolean deleteFile (File destFile) { if ( destFile.exists() ) { SimpleDateFormat sdf = (SimpleDateFormat)stamp.get(); String f = sdf.format (new java.util.Date()); File deleteTo = new File (destFile.getParentFile (), destFile.getName () + "-" + f + ".old"); int count = 1; while ( deleteTo.exists () ) { deleteTo = new File (destFile.getParentFile (), destFile.getName () + "-" + f + "-" + count + ".old"); count++; } return destFile.renameTo (deleteTo); } return true; } /** * Recht umfangreiches Script, dass versucht die newStart-Datei zu installieren. * @param newStart Die neue Datei. * @return true, wenn Installation erfolgreich war. */ private static boolean appUpdateStart (File newStart, String appID) { if ( newStart == null ) return false; final String replaceName = newStart.getName (); final String errorHeader = "Fehler beim Installieren der " + replaceName; try { newStart = new File (new File (Pool.getPathRelative (false), "updates/incoming/"), newStart.getName ()); File currentFolder = new File (".").getCanonicalFile (); while ( currentFolder != null && !currentFolder.getName ().equalsIgnoreCase (appID) ) { currentFolder = currentFolder.getParentFile (); } if ( currentFolder != null && currentFolder.getName ().equalsIgnoreCase (appID) ) { File oldStart = new File (currentFolder, replaceName); if ( deleteFile (oldStart) ) { if ( !newStart.renameTo (oldStart) ) { Pool.writeLogFile ("[APPUpdate] " + newStart.getAbsolutePath () + " updated to " + oldStart.getAbsolutePath ()); return true; } else { Pool.showError (null, errorHeader, "Die neue " + replaceName + "-Datei konnte nicht verschoben werden.", true); } } else { Pool.showError (null, errorHeader, "Die alte " + replaceName + "-Datei konnte nicht gelöscht werden.", true); } } else { Pool.showError (null, errorHeader, "Der Hauptordner ''sepix\\s3'' konnte nicht gefunden werden.\n" + "Bitte wählen Sie den Ordner aus, in der die Datei ''" + replaceName + "'' ersetzt werden soll.", true); currentFolder = JFileSecureChooser.getSelectedPath (null, new File ("c:\\programme\\sepix\\s3")); if ( currentFolder != null ) { File oldStart = new File (currentFolder, replaceName); while ( !oldStart.exists () ) { if ( !Pool.askForAction (null, "In dem Ordner findet sich keine alte " + replaceName + "-Datei. Weiter suchen?") ) { break; } currentFolder = JFileSecureChooser.getSelectedPath (null, currentFolder); if ( currentFolder == null ) break; oldStart = new File (currentFolder, replaceName); } } if ( currentFolder != null ) { File oldStart = new File (currentFolder, replaceName); if ( oldStart.exists () ) { if ( deleteFile (oldStart) ) { if ( newStart.renameTo (oldStart) ) { Pool.writeLogFile ("[APPUpdate] " + newStart.getAbsolutePath () + " updated to " + oldStart.getAbsolutePath ()); return true; } else { Pool.showError (null, errorHeader, "Die neue " + replaceName + "-Datei konnte nicht verschoben werden.", true); } } else { Pool.showError (null, errorHeader, "Die alte " + replaceName + "-Datei konnte nicht gelöscht werden.", true); } } } } } catch ( IOException ioe ) { Pool.showError (ioe, errorHeader, ioe.getLocalizedMessage (), true); } return false; } }