2014-04-19 02:30:29 -04:00
package net.filebot ;
2009-01-04 13:28:28 -05:00
2012-07-14 03:58:53 -04:00
import static java.awt.GraphicsEnvironment.* ;
2016-03-09 11:02:36 -05:00
import static java.util.Arrays.* ;
2016-03-07 07:30:12 -05:00
import static java.util.stream.Collectors.* ;
2016-03-02 10:55:06 -05:00
import static net.filebot.Logging.* ;
2014-04-19 02:30:29 -04:00
import static net.filebot.Settings.* ;
import static net.filebot.util.FileUtilities.* ;
2016-03-07 07:30:12 -05:00
import static net.filebot.util.XPathUtilities.* ;
2014-07-29 02:45:15 -04:00
import static net.filebot.util.ui.SwingUI.* ;
2009-03-13 20:30:24 -04:00
2012-07-14 03:58:53 -04:00
import java.awt.Dialog.ModalityType ;
import java.awt.event.WindowAdapter ;
import java.awt.event.WindowEvent ;
import java.io.File ;
import java.io.IOException ;
2013-03-30 00:20:56 -04:00
import java.io.OutputStream ;
2016-03-07 07:30:12 -05:00
import java.net.URL ;
2013-03-30 00:20:56 -04:00
import java.nio.channels.Channels ;
import java.nio.channels.FileChannel ;
2014-11-06 23:54:21 -05:00
import java.nio.file.StandardOpenOption ;
2012-07-14 03:58:53 -04:00
import java.security.CodeSource ;
import java.security.Permission ;
import java.security.PermissionCollection ;
import java.security.Permissions ;
import java.security.Policy ;
import java.security.ProtectionDomain ;
2016-03-19 10:42:40 -04:00
import java.util.List ;
2016-03-07 07:30:12 -05:00
import java.util.Map ;
2016-03-09 14:26:00 -05:00
import java.util.logging.Handler ;
2012-07-14 03:58:53 -04:00
import java.util.logging.Level ;
import javax.swing.JDialog ;
import javax.swing.JFrame ;
import javax.swing.JLabel ;
import javax.swing.JPanel ;
import javax.swing.SwingUtilities ;
import javax.swing.UIManager ;
2016-03-10 14:43:21 -05:00
import org.kohsuke.args4j.CmdLineException ;
import org.w3c.dom.Document ;
2016-03-11 06:14:50 -05:00
import net.filebot.Settings.ApplicationFolder ;
2014-04-19 02:30:29 -04:00
import net.filebot.cli.ArgumentBean ;
import net.filebot.cli.ArgumentProcessor ;
import net.filebot.format.ExpressionFormat ;
2014-08-05 07:55:28 -04:00
import net.filebot.mac.MacAppUtilities ;
2015-05-09 04:07:38 -04:00
import net.filebot.ui.FileBotMenuBar ;
2015-05-10 14:06:04 -04:00
import net.filebot.ui.GettingStartedStage ;
2014-04-19 02:30:29 -04:00
import net.filebot.ui.MainFrame ;
2016-03-09 11:18:20 -05:00
import net.filebot.ui.NotificationHandler ;
2014-04-19 02:30:29 -04:00
import net.filebot.ui.PanelBuilder ;
import net.filebot.ui.SinglePanelFrame ;
2016-04-23 13:05:33 -04:00
import net.filebot.ui.SupportDialog ;
2014-08-27 08:08:00 -04:00
import net.filebot.ui.transfer.FileTransferable ;
2014-04-19 02:30:29 -04:00
import net.filebot.util.PreferencesMap.PreferencesEntry ;
import net.filebot.util.TeePrintStream ;
2016-04-16 17:41:13 -04:00
import net.filebot.util.ui.SwingEventBus ;
2014-06-23 11:09:43 -04:00
import net.miginfocom.swing.MigLayout ;
2009-03-14 06:20:59 -04:00
2007-12-23 14:28:04 -05:00
public class Main {
2013-10-17 03:11:03 -04:00
2014-04-13 15:35:23 -04:00
public static void main ( String [ ] argumentArray ) {
2012-07-14 03:58:53 -04:00
try {
// parse arguments
2016-03-11 03:16:57 -05:00
ArgumentBean args = ArgumentBean . parse ( argumentArray ) ;
2013-10-17 03:11:03 -04:00
2013-12-23 22:24:02 -05:00
if ( args . printHelp ( ) | | args . printVersion ( ) | | ( ! ( args . runCLI ( ) | | args . clearCache ( ) | | args . clearUserData ( ) ) & & isHeadless ( ) ) ) {
2012-07-14 03:58:53 -04:00
System . out . format ( " %s / %s%n%n " , getApplicationIdentifier ( ) , getJavaRuntimeIdentifier ( ) ) ;
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
if ( args . printHelp ( ) | | ( ! args . printVersion ( ) & & isHeadless ( ) ) ) {
2014-04-15 08:14:43 -04:00
ArgumentBean . printHelp ( args , System . out ) ;
2012-07-14 03:58:53 -04:00
}
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
// just print help message or version string and then exit
System . exit ( 0 ) ;
}
2013-10-17 03:11:03 -04:00
2013-11-07 02:43:58 -05:00
if ( args . clearCache ( ) | | args . clearUserData ( ) ) {
if ( args . clearUserData ( ) ) {
2016-03-10 09:05:56 -05:00
System . out . println ( " Reset preferences " ) ;
2013-11-07 02:43:58 -05:00
Settings . forPackage ( Main . class ) . clear ( ) ;
}
2016-03-08 11:21:07 -05:00
// clear preferences and cache
2013-11-07 02:43:58 -05:00
if ( args . clearCache ( ) ) {
2016-03-17 05:03:22 -04:00
System . out . println ( " Clear cache " ) ;
for ( File folder : getChildren ( ApplicationFolder . Cache . getCanonicalFile ( ) , FOLDERS ) ) {
if ( delete ( folder ) ) {
System . out . println ( " * Delete " + folder ) ;
} else {
System . out . println ( " * Failed to delete " + folder ) ;
}
2013-11-07 02:43:58 -05:00
}
}
// just clear cache and/or settings and then exit
System . exit ( 0 ) ;
}
2016-03-11 03:16:57 -05:00
// make sure we can access application arguments at any time
setApplicationArgumentArray ( argumentArray ) ;
2016-03-08 11:21:10 -05:00
// update system properties
initializeSystemProperties ( args ) ;
2016-03-10 09:05:56 -05:00
initializeLogging ( args ) ;
2013-10-17 03:11:03 -04:00
2012-12-11 06:19:14 -05:00
// make sure java.io.tmpdir exists
2016-03-11 06:14:50 -05:00
createFolders ( ApplicationFolder . Temp . get ( ) ) ;
2013-10-17 03:11:03 -04:00
2012-10-27 22:52:49 -04:00
// initialize this stuff before anything else
2016-03-06 13:11:30 -05:00
CacheManager . getInstance ( ) ;
2012-10-27 22:52:49 -04:00
initializeSecurityManager ( ) ;
2013-10-17 03:11:03 -04:00
2014-11-10 03:18:32 -05:00
// initialize history spooler
2016-03-05 16:06:26 -05:00
HistorySpooler . getInstance ( ) . setPersistentHistoryEnabled ( useRenameHistory ( ) ) ;
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
// CLI mode => run command-line interface and then exit
if ( args . runCLI ( ) ) {
2016-03-10 13:32:11 -05:00
int status = new ArgumentProcessor ( ) . run ( args ) ;
2012-07-14 03:58:53 -04:00
System . exit ( status ) ;
}
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
// GUI mode => start user interface
2016-03-20 03:52:13 -04:00
SwingUtilities . invokeAndWait ( ( ) - > {
startUserInterface ( args ) ;
} ) ;
// publish file arguments
List < File > files = args . getFiles ( false ) ;
if ( files . size ( ) > 0 ) {
SwingEventBus . getInstance ( ) . post ( new FileTransferable ( files ) ) ;
}
2013-10-17 03:11:03 -04:00
2016-05-10 09:19:02 -04:00
// wait for UI to startup completely before loading more classes
Thread . sleep ( 1000 ) ;
2015-01-01 15:29:00 -05:00
// preload media.types (when loaded during DnD it will freeze the UI for a few hundred milliseconds)
2012-07-14 10:50:07 -04:00
MediaTypes . getDefault ( ) ;
2014-01-12 14:22:14 -05:00
2016-05-10 09:19:02 -04:00
// JavaFX is used for ProgressMonitor and GettingStartedDialog
try {
initJavaFX ( ) ;
} catch ( Throwable e ) {
debug . log ( Level . WARNING , " Failed to initialize JavaFX " , e ) ;
}
2016-05-10 09:20:43 -04:00
// check if application help should be shown
if ( ! " skip " . equals ( System . getProperty ( " application.help " ) ) ) {
2012-07-14 03:58:53 -04:00
try {
2016-05-10 09:20:43 -04:00
checkGettingStarted ( ) ;
2016-05-03 15:06:58 -04:00
} catch ( Throwable e ) {
2016-05-10 09:20:43 -04:00
debug . log ( Level . WARNING , " Failed to show Getting Started help " , e ) ;
2012-07-14 03:58:53 -04:00
}
}
2015-05-10 14:06:04 -04:00
2016-05-10 09:20:43 -04:00
// check for application updates
if ( ! " skip " . equals ( System . getProperty ( " application.update " ) ) ) {
2015-05-10 14:06:04 -04:00
try {
2016-05-10 09:20:43 -04:00
checkUpdate ( ) ;
2016-05-03 15:06:58 -04:00
} catch ( Throwable e ) {
2016-05-10 09:20:43 -04:00
debug . log ( Level . WARNING , " Failed to check for updates " , e ) ;
2015-05-10 14:06:04 -04:00
}
}
2015-10-11 12:56:01 -04:00
} catch ( CmdLineException e ) {
// illegal arguments => print CLI error message
2012-07-14 03:58:53 -04:00
System . err . println ( e . getMessage ( ) ) ;
System . exit ( - 1 ) ;
2015-10-11 12:56:01 -04:00
} catch ( Throwable e ) {
2016-03-11 03:16:57 -05:00
// find root cause
while ( e . getCause ( ) ! = null ) {
e = e . getCause ( ) ;
}
2015-10-11 12:56:01 -04:00
// unexpected error => dump stack
2016-03-11 03:16:57 -05:00
debug . log ( Level . SEVERE , String . format ( " Error during startup: %s " , e . getMessage ( ) ) , e ) ;
2015-10-11 12:56:01 -04:00
System . exit ( - 1 ) ;
2012-07-14 03:58:53 -04:00
}
}
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
private static void startUserInterface ( ArgumentBean args ) {
2016-03-10 09:05:56 -05:00
// use native LaF an all platforms
2016-03-09 11:02:36 -05:00
try {
UIManager . setLookAndFeel ( UIManager . getSystemLookAndFeelClassName ( ) ) ;
} catch ( Exception e ) {
2016-03-09 15:36:28 -05:00
debug . log ( Level . SEVERE , e . getMessage ( ) , e ) ;
2016-03-09 11:02:36 -05:00
}
// default frame
2016-03-20 03:52:13 -04:00
JFrame frame = new MainFrame ( PanelBuilder . defaultSequence ( ) ) ;
2016-03-09 11:02:36 -05:00
// single panel frame
if ( args . mode ! = null ) {
2016-03-19 12:53:37 -04:00
PanelBuilder [ ] selection = stream ( PanelBuilder . defaultSequence ( ) ) . filter ( p - > p . getName ( ) . matches ( args . mode ) ) . toArray ( PanelBuilder [ ] : : new ) ;
2015-12-14 04:47:29 -05:00
if ( selection . length = = 1 ) {
2016-03-20 03:52:13 -04:00
frame = new SinglePanelFrame ( selection [ 0 ] ) ;
2015-12-14 04:50:42 -05:00
} else if ( selection . length > 1 ) {
2016-03-20 03:52:13 -04:00
frame = new MainFrame ( selection ) ;
2015-12-14 04:47:29 -05:00
} else {
2013-04-09 13:55:54 -04:00
throw new IllegalArgumentException ( " Illegal mode: " + args . mode ) ;
}
2012-07-14 03:58:53 -04:00
}
2016-03-19 10:42:40 -04:00
2013-04-09 14:20:52 -04:00
try {
// restore previous size and location
restoreWindowBounds ( frame , Settings . forPackage ( MainFrame . class ) ) ;
} catch ( Exception e ) {
2014-12-22 13:58:24 -05:00
// make sure the main window is not displayed out of screen bounds
frame . setLocation ( 120 , 80 ) ;
2013-04-09 14:20:52 -04:00
}
2013-10-17 03:11:03 -04:00
2013-02-25 12:27:34 -05:00
frame . addWindowListener ( new WindowAdapter ( ) {
2013-10-17 03:11:03 -04:00
2013-02-25 12:27:34 -05:00
@Override
public void windowClosing ( WindowEvent e ) {
e . getWindow ( ) . setVisible ( false ) ;
2014-10-09 13:30:43 -04:00
2016-03-09 11:02:36 -05:00
// make sure any long running operations are done now and not later on the shutdown hook thread
2013-02-25 12:27:34 -05:00
HistorySpooler . getInstance ( ) . commit ( ) ;
2016-04-23 13:05:33 -04:00
SupportDialog . maybeShow ( ) ;
2013-10-17 03:11:03 -04:00
2013-02-25 12:27:34 -05:00
System . exit ( 0 ) ;
}
} ) ;
2013-10-17 03:11:03 -04:00
2014-10-18 11:52:35 -04:00
// configure main window
2014-10-09 09:37:15 -04:00
if ( isMacApp ( ) ) {
2014-10-18 11:52:35 -04:00
// Mac OS X specific configuration
2014-10-09 09:37:15 -04:00
MacAppUtilities . initializeApplication ( ) ;
2014-08-05 07:55:28 -04:00
MacAppUtilities . setWindowCanFullScreen ( frame ) ;
2015-05-09 04:07:38 -04:00
MacAppUtilities . setDefaultMenuBar ( FileBotMenuBar . createHelp ( ) ) ;
2016-03-20 03:52:13 -04:00
MacAppUtilities . setOpenFileHandler ( openFiles - > SwingEventBus . getInstance ( ) . post ( new FileTransferable ( openFiles ) ) ) ;
2015-05-17 08:46:31 -04:00
} else if ( isUbuntuApp ( ) ) {
// Ubuntu specific configuration
2015-05-18 11:41:26 -04:00
String options = System . getenv ( " JAVA_TOOL_OPTIONS " ) ;
if ( options ! = null & & options . contains ( " jayatanaag.jar " ) ) {
2016-03-09 11:02:36 -05:00
// menu should be rendered via JAyatana on Ubuntu 15.04 and higher
frame . setJMenuBar ( FileBotMenuBar . createHelp ( ) ) ;
2015-05-18 11:41:26 -04:00
}
2015-05-17 08:46:31 -04:00
frame . setIconImages ( ResourceManager . getApplicationIcons ( ) ) ;
2014-10-18 11:52:35 -04:00
} else {
// Windows / Linux specific configuration
2015-05-10 16:33:21 -04:00
frame . setIconImages ( ResourceManager . getApplicationIcons ( ) ) ;
2014-07-30 21:20:27 -04:00
}
2012-07-14 03:58:53 -04:00
// start application
2015-05-09 04:07:38 -04:00
frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE ) ;
2012-07-14 03:58:53 -04:00
frame . setVisible ( true ) ;
}
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
/ * *
* Show update notifications if updates are available
* /
private static void checkUpdate ( ) throws Exception {
2016-03-07 07:30:12 -05:00
Cache cache = Cache . getCache ( getApplicationName ( ) , CacheType . Persistent ) ;
2016-03-07 11:01:10 -05:00
Document dom = cache . xml ( " update.url " , s - > new URL ( getApplicationProperty ( s ) ) ) . expire ( Cache . ONE_WEEK ) . retry ( 0 ) . get ( ) ;
2013-10-17 03:11:03 -04:00
2016-03-07 07:30:12 -05:00
// parse update xml
2016-03-09 00:58:39 -05:00
final Map < String , String > update = streamElements ( dom . getFirstChild ( ) ) . collect ( toMap ( n - > {
return n . getNodeName ( ) ;
} , n - > {
return n . getTextContent ( ) . trim ( ) ;
} ) ) ;
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
// check if update is required
2016-03-07 07:30:12 -05:00
int latestRev = Integer . parseInt ( update . get ( " revision " ) ) ;
2013-10-17 03:11:03 -04:00
int currentRev = getApplicationRevisionNumber ( ) ;
if ( latestRev > currentRev & & currentRev > 0 ) {
2016-03-07 07:30:12 -05:00
SwingUtilities . invokeLater ( ( ) - > {
final JDialog dialog = new JDialog ( JFrame . getFrames ( ) [ 0 ] , update . get ( " title " ) , ModalityType . APPLICATION_MODAL ) ;
final JPanel pane = new JPanel ( new MigLayout ( " fill, nogrid, insets dialog " ) ) ;
dialog . setContentPane ( pane ) ;
2013-10-17 03:11:03 -04:00
2016-03-07 07:30:12 -05:00
pane . add ( new JLabel ( ResourceManager . getIcon ( " window.icon.medium " ) ) , " aligny top " ) ;
pane . add ( new JLabel ( update . get ( " message " ) ) , " gap 10, wrap paragraph:push " ) ;
2013-10-17 03:11:03 -04:00
2016-03-07 07:30:12 -05:00
pane . add ( newButton ( " Download " , ResourceManager . getIcon ( " dialog.continue " ) , evt - > {
openURI ( update . get ( " download " ) ) ;
dialog . setVisible ( false ) ;
} ) , " tag ok " ) ;
pane . add ( newButton ( " Details " , ResourceManager . getIcon ( " action.report " ) , evt - > {
openURI ( update . get ( " discussion " ) ) ;
} ) , " tag help2 " ) ;
pane . add ( newButton ( " Ignore " , ResourceManager . getIcon ( " dialog.cancel " ) , evt - > {
dialog . setVisible ( false ) ;
} ) , " tag cancel " ) ;
dialog . pack ( ) ;
dialog . setLocation ( getOffsetLocation ( dialog . getOwner ( ) ) ) ;
dialog . setVisible ( true ) ;
2012-07-14 03:58:53 -04:00
} ) ;
}
}
2013-10-17 03:11:03 -04:00
2015-05-10 14:06:04 -04:00
/ * *
* Show Getting Started to new users
* /
private static void checkGettingStarted ( ) throws Exception {
PreferencesEntry < String > started = Settings . forPackage ( Main . class ) . entry ( " getting.started " ) . defaultValue ( " 0 " ) ;
if ( " 0 " . equals ( started . getValue ( ) ) ) {
2015-09-12 11:49:47 -04:00
started . setValue ( " 1 " ) ;
started . flush ( ) ;
2016-03-07 07:30:12 -05:00
// open Getting Started
SwingUtilities . invokeLater ( ( ) - > GettingStartedStage . start ( ) ) ;
2015-05-10 14:06:04 -04:00
}
}
2012-07-14 03:58:53 -04:00
private static void restoreWindowBounds ( final JFrame window , final Settings settings ) {
// store bounds on close
window . addWindowListener ( new WindowAdapter ( ) {
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
@Override
public void windowClosing ( WindowEvent e ) {
// don't save window bounds if window is maximized
if ( ! isMaximized ( window ) ) {
settings . put ( " window.x " , String . valueOf ( window . getX ( ) ) ) ;
settings . put ( " window.y " , String . valueOf ( window . getY ( ) ) ) ;
settings . put ( " window.width " , String . valueOf ( window . getWidth ( ) ) ) ;
settings . put ( " window.height " , String . valueOf ( window . getHeight ( ) ) ) ;
}
}
} ) ;
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
// restore bounds
int x = Integer . parseInt ( settings . get ( " window.x " ) ) ;
int y = Integer . parseInt ( settings . get ( " window.y " ) ) ;
int width = Integer . parseInt ( settings . get ( " window.width " ) ) ;
int height = Integer . parseInt ( settings . get ( " window.height " ) ) ;
window . setBounds ( x , y , width , height ) ;
}
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
/ * *
2013-02-07 03:34:08 -05:00
* Initialize default SecurityManager and grant all permissions via security policy . Initialization is required in order to run { @link ExpressionFormat } in a secure sandbox .
2012-07-14 03:58:53 -04:00
* /
private static void initializeSecurityManager ( ) {
try {
// initialize security policy used by the default security manager
// because default the security policy is very restrictive (e.g. no FilePermission)
Policy . setPolicy ( new Policy ( ) {
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
@Override
public boolean implies ( ProtectionDomain domain , Permission permission ) {
// all permissions
return true ;
}
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
@Override
public PermissionCollection getPermissions ( CodeSource codesource ) {
2013-10-17 03:11:03 -04:00
// VisualVM can't connect if this method does return
2012-07-14 03:58:53 -04:00
// a checked immutable PermissionCollection
return new Permissions ( ) ;
}
} ) ;
2013-10-17 03:11:03 -04:00
2012-07-14 03:58:53 -04:00
// set default security manager
System . setSecurityManager ( new SecurityManager ( ) ) ;
} catch ( Exception e ) {
// security manager was probably set via system property
2016-03-09 15:36:28 -05:00
debug . log ( Level . WARNING , e . getMessage ( ) , e ) ;
2012-07-14 03:58:53 -04:00
}
2009-05-02 19:34:04 -04:00
}
2013-10-17 03:11:03 -04:00
2016-03-08 11:21:10 -05:00
public static void initializeSystemProperties ( ArgumentBean args ) {
System . setProperty ( " http.agent " , String . format ( " %s %s " , getApplicationName ( ) , getApplicationVersion ( ) ) ) ;
System . setProperty ( " sun.net.client.defaultConnectTimeout " , " 10000 " ) ;
System . setProperty ( " sun.net.client.defaultReadTimeout " , " 60000 " ) ;
System . setProperty ( " swing.crossplatformlaf " , " javax.swing.plaf.nimbus.NimbusLookAndFeel " ) ;
2016-03-11 06:14:50 -05:00
System . setProperty ( " grape.root " , ApplicationFolder . AppData . resolve ( " grape " ) . getAbsolutePath ( ) ) ;
2016-03-08 11:21:10 -05:00
System . setProperty ( " org.apache.commons.logging.Log " , " org.apache.commons.logging.impl.NoOpLog " ) ;
2016-05-07 05:01:39 -04:00
if ( args . unixfs ) {
System . setProperty ( " unixfs " , " true " ) ;
}
if ( args . disableExtendedAttributes ) {
System . setProperty ( " useExtendedFileAttributes " , " false " ) ;
System . setProperty ( " useCreationDate " , " false " ) ;
}
if ( args . action . equalsIgnoreCase ( " test " ) ) {
System . setProperty ( " application.rename.history " , " false " ) ; // do not keep history of --action test rename operations
}
2016-03-08 11:21:10 -05:00
}
2016-03-10 09:05:56 -05:00
public static void initializeLogging ( ArgumentBean args ) throws IOException {
2016-03-15 10:57:21 -04:00
if ( args . runCLI ( ) ) {
// CLI logging settings
log . setLevel ( args . getLogLevel ( ) ) ;
} else {
// GUI logging settings
log . setLevel ( Level . INFO ) ;
log . addHandler ( new NotificationHandler ( getApplicationName ( ) ) ) ;
// log errors to file
try {
Handler error = createSimpleFileHandler ( ApplicationFolder . AppData . resolve ( " error.log " ) , Level . WARNING ) ;
log . addHandler ( error ) ;
debug . addHandler ( error ) ;
} catch ( Exception e ) {
debug . log ( Level . WARNING , " Failed to initialize error log " , e ) ;
}
}
2016-03-10 09:05:56 -05:00
// tee stdout and stderr to log file if set
if ( args . logFile ! = null ) {
File logFile = new File ( args . logFile ) ;
if ( ! logFile . isAbsolute ( ) ) {
2016-03-11 06:14:50 -05:00
logFile = new File ( ApplicationFolder . AppData . resolve ( " logs " ) , logFile . getPath ( ) ) . getAbsoluteFile ( ) ; // by default resolve relative paths against {applicationFolder}/logs/{logFile}
2016-03-10 09:05:56 -05:00
}
if ( ! logFile . exists ( ) & & ! logFile . getParentFile ( ) . mkdirs ( ) & & ! logFile . createNewFile ( ) ) {
throw new IOException ( " Failed to create log file: " + logFile ) ;
}
// open file channel and lock
FileChannel logChannel = FileChannel . open ( logFile . toPath ( ) , StandardOpenOption . CREATE , StandardOpenOption . WRITE , StandardOpenOption . APPEND ) ;
if ( args . logLock ) {
2016-04-16 17:41:13 -04:00
try {
2016-03-15 10:57:21 -04:00
log . config ( " Locking " + logFile ) ;
2016-04-16 17:41:13 -04:00
logChannel . lock ( ) ;
} catch ( Exception e ) {
throw new IOException ( " Failed to acquire lock: " + logFile , e ) ;
2016-03-10 09:05:56 -05:00
}
}
OutputStream out = Channels . newOutputStream ( logChannel ) ;
System . setOut ( new TeePrintStream ( out , true , " UTF-8 " , System . out ) ) ;
System . setErr ( new TeePrintStream ( out , true , " UTF-8 " , System . err ) ) ;
}
}
2007-12-23 14:28:04 -05:00
}