Moving gwt logging over from the IO branch. Changed the gwt.logging property to gwt.logging.enabled so that it doesn't conflict for projects using the incubator which already defines gwt.logging Review by: spoon@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8260 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java b/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java index d9dc1de..2281eae 100644 --- a/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java +++ b/dev/core/src/com/google/gwt/dev/shell/ModuleSpace.java
@@ -303,7 +303,10 @@ type = TreeLogger.ERROR; } // Log at the top level for visibility. - getLogger().log(type, message, e); + TreeLogger t = getLogger(); + if (t != null) { + getLogger().log(type, message, e); + } } /**
diff --git a/user/src/com/google/gwt/logging/LogImpl.gwt.xml b/user/src/com/google/gwt/logging/LogImpl.gwt.xml new file mode 100644 index 0000000..ddf32b1 --- /dev/null +++ b/user/src/com/google/gwt/logging/LogImpl.gwt.xml
@@ -0,0 +1,17 @@ +<module> + <source path="impl" /> + + <!-- Set up and handle the gwt.logging property --> + <define-property name="gwt.logging.enabled" values="TRUE, FALSE" /> + <replace-with class="com.google.gwt.logging.impl.LoggerImplRegular"> + <when-type-is class="com.google.gwt.logging.impl.LoggerImplNull"/> + <when-property-is name="gwt.logging.enabled" value="TRUE" /> + </replace-with> + <replace-with class="com.google.gwt.logging.impl.LevelImplRegular"> + <when-type-is class="com.google.gwt.logging.impl.LevelImplNull"/> + <when-property-is name="gwt.logging.enabled" value="TRUE" /> + </replace-with> + + <set-property name="gwt.logging.enabled" value="FALSE"/> + +</module> \ No newline at end of file
diff --git a/user/src/com/google/gwt/logging/Logging.gwt.xml b/user/src/com/google/gwt/logging/Logging.gwt.xml new file mode 100644 index 0000000..ee40d37 --- /dev/null +++ b/user/src/com/google/gwt/logging/Logging.gwt.xml
@@ -0,0 +1,98 @@ +<!-- --> +<!-- Copyright 2010 Google Inc. --> +<!-- Licensed under the Apache License, Version 2.0 (the "License"); you --> +<!-- may not use this file except in compliance with the License. You may --> +<!-- may obtain a copy of the License at --> +<!-- --> +<!-- http://www.apache.org/licenses/LICENSE-2.0 --> +<!-- --> +<!-- Unless required by applicable law or agreed to in writing, software --> +<!-- distributed under the License is distributed on an "AS IS" BASIS, --> +<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or --> +<!-- implied. License for the specific language governing permissions and --> +<!-- limitations under the License. --> + +<!-- regular expressions support. --> +<module> + <inherits name="com.google.gwt.logging.LogImpl"/> + + <replace-with class="com.google.gwt.logging.client.LogConfiguration.LogConfigurationImplRegular"> + <when-type-is class="com.google.gwt.logging.client.LogConfiguration.LogConfigurationImplNull"/> + <when-property-is name="gwt.logging.enabled" value="TRUE" /> + </replace-with> + + + <!-- Set up and handle the gwt.logging.logLevel property --> + <define-property name="gwt.logging.logLevel" values="ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE" /> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.All"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="ALL" /> + </replace-with> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.Finest"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="FINEST" /> + </replace-with> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.Finer"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="FINER" /> + </replace-with> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.Fine"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="FINE" /> + </replace-with> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.Config"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="CONFIG" /> + </replace-with> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.Info"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="INFO" /> + </replace-with> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.Warning"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="WARNING" /> + </replace-with> + <replace-with class="com.google.gwt.logging.client.DefaultLevel.Severe"> + <when-type-is class="com.google.gwt.logging.client.DefaultLevel" /> + <when-property-is name="gwt.logging.logLevel" value="SEVERE" /> + </replace-with> + + + <!-- Set up and handle the gwt.logging.xxxHandler properties --> + <define-property name="gwt.logging.consoleHandler" values="ENABLED, DISABLED" /> + <replace-with class="com.google.gwt.logging.client.NullLogHandler"> + <when-type-is class="com.google.gwt.logging.client.ConsoleLogHandler" /> + <when-property-is name="gwt.logging.consoleHandler" value="DISABLED" /> + </replace-with> + <define-property name="gwt.logging.developmentModeHandler" values="ENABLED, DISABLED" /> + <replace-with class="com.google.gwt.logging.client.NullLogHandler"> + <when-type-is class="com.google.gwt.logging.client.DevelopmentModeLogHandler" /> + <when-property-is name="gwt.logging.developmentModeHandler" value="DISABLED" /> + </replace-with> + <define-property name="gwt.logging.firebugHandler" values="ENABLED, DISABLED" /> + <replace-with class="com.google.gwt.logging.client.NullLogHandler"> + <when-type-is class="com.google.gwt.logging.client.FirebugLogHandler" /> + <when-property-is name="gwt.logging.firebugHandler" value="DISABLED" /> + </replace-with> + <define-property name="gwt.logging.systemHandler" values="ENABLED, DISABLED" /> + <replace-with class="com.google.gwt.logging.client.NullLogHandler"> + <when-type-is class="com.google.gwt.logging.client.SystemLogHandler" /> + <when-property-is name="gwt.logging.systemHandler" value="DISABLED" /> + </replace-with> + <define-property name="gwt.logging.popupHandler" values="ENABLED, DISABLED" /> + <replace-with class="com.google.gwt.logging.client.NullLoggingPopup"> + <when-type-is class="com.google.gwt.logging.client.BasicLoggingPopup" /> + <when-property-is name="gwt.logging.popupHandler" value="DISABLED" /> + </replace-with> + + <!-- Default values for all properties --> + <set-property name="gwt.logging.enabled" value="TRUE"/> + <set-property name="gwt.logging.logLevel" value="INFO"/> + <set-property name="gwt.logging.consoleHandler" value="ENABLED" /> + <set-property name="gwt.logging.developmentModeHandler" value="ENABLED" /> + <set-property name="gwt.logging.firebugHandler" value="ENABLED" /> + <set-property name="gwt.logging.popupHandler" value="ENABLED" /> + <set-property name="gwt.logging.systemHandler" value="ENABLED" /> + + <entry-point class="com.google.gwt.logging.client.LogConfiguration"/> +</module> \ No newline at end of file
diff --git a/user/src/com/google/gwt/logging/client/BasicLoggingPopup.java b/user/src/com/google/gwt/logging/client/BasicLoggingPopup.java new file mode 100644 index 0000000..bb678bf --- /dev/null +++ b/user/src/com/google/gwt/logging/client/BasicLoggingPopup.java
@@ -0,0 +1,66 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.Widget; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; + +/** + * A simple popup to show log messages + */ +public class BasicLoggingPopup extends DialogBox { + private VerticalPanel v; + + // TODO(unnurg): Make this into a popup that is less intrusive to the + // running of the application. + public BasicLoggingPopup() { + super(false, false); + ScrollPanel s = new ScrollPanel(); + v = new VerticalPanel(); + s.setWidget(v); + s.setAlwaysShowScrollBars(true); + s.setHeight("100px"); + super.setWidget(s); + setText("Logging"); + Button ok = new Button("OK"); + ok.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + hide(); + } + }); + v.add(ok); + show(); + } + + @Override + public void add(Widget w) { + v.add(w); + } + + @Override + public void setWidget(Widget w) { + v.clear(); + v.add(w); + } + + +}
diff --git a/user/src/com/google/gwt/logging/client/ConsoleLogHandler.java b/user/src/com/google/gwt/logging/client/ConsoleLogHandler.java new file mode 100644 index 0000000..c8a1853 --- /dev/null +++ b/user/src/com/google/gwt/logging/client/ConsoleLogHandler.java
@@ -0,0 +1,66 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * A Handler that prints logs to the window.console - this is used by things + * like FirebugLite in IE, and Safari debug mode. + * Note we are consciously using 'window' rather than '$wnd' to avoid issues + * similar to http://code.google.com/p/fbug/issues/detail?id=2914 + */ +public class ConsoleLogHandler extends Handler { + + public ConsoleLogHandler() { + setFormatter(new TextLogFormatter()); + setLevel(Level.ALL); + } + + @Override + public void close() { + // No action needed + } + + @Override + public void flush() { + // No action needed + } + + @Override + public void publish(LogRecord record) { + if (!isSupported() || !isLoggable(record)) { + return; + } + String msg = getFormatter().format(record); + log(msg); + } + + private native boolean isSupported() /*-{ + return ((window.console != null) && + (window.console.firebug == null) && + (window.console.log != null) && + (typeof(window.console.log) == 'function')); + }-*/; + + private native void log(String message) /*-{ + window.console.log(message); + }-*/; + +}
diff --git a/user/src/com/google/gwt/logging/client/DefaultLevel.java b/user/src/com/google/gwt/logging/client/DefaultLevel.java new file mode 100644 index 0000000..c25bd47 --- /dev/null +++ b/user/src/com/google/gwt/logging/client/DefaultLevel.java
@@ -0,0 +1,101 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import java.util.logging.Level; + +/** + * An interface for a set of classes which are used to choose the default + * logging level. This allows the user to configure the default level in the + * gwt.xml file. + */ +public interface DefaultLevel { + /** + * Returns Level.ALL as the default level + */ + public class All implements DefaultLevel { + public Level getLevel() { + return Level.ALL; + } + } + + /** + * Returns Level.CONFIG as the default level + */ + public class Config implements DefaultLevel { + public Level getLevel() { + return Level.CONFIG; + } + } + + /** + * Returns Level.FINE as the default level + */ + public class Fine implements DefaultLevel { + public Level getLevel() { + return Level.FINE; + } + } + + /** + * Returns Level.FINER as the default level + */ + public class Finer implements DefaultLevel { + public Level getLevel() { + return Level.FINER; + } + } + + /** + * Returns Level.FINEST as the default level + */ + public class Finest implements DefaultLevel { + public Level getLevel() { + return Level.FINEST; + } + } + + /** + * Returns Level.INFO as the default level + */ + public class Info implements DefaultLevel { + public Level getLevel() { + return Level.INFO; + } + } + + /** + * Returns Level.SEVERE as the default level + */ + public class Severe implements DefaultLevel { + public Level getLevel() { + return Level.SEVERE; + } + } + + /** + * Returns Level.WARNING as the default level + */ + public class Warning implements DefaultLevel { + public Level getLevel() { + return Level.WARNING; + } + } + + Level getLevel(); + +}
diff --git a/user/src/com/google/gwt/logging/client/DevelopmentModeLogHandler.java b/user/src/com/google/gwt/logging/client/DevelopmentModeLogHandler.java new file mode 100644 index 0000000..188fdcb --- /dev/null +++ b/user/src/com/google/gwt/logging/client/DevelopmentModeLogHandler.java
@@ -0,0 +1,61 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import com.google.gwt.core.client.GWT; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * A Handler that prints logs to GWT.log, causing the messages to show up in + * the Development Mode tab in Eclipse when running in Development mode. + */ +public class DevelopmentModeLogHandler extends Handler { + + public DevelopmentModeLogHandler() { + setFormatter(new TextLogFormatter()); + setLevel(Level.ALL); + } + + @Override + public void close() { + // No action needed + } + + @Override + public void flush() { + // No action needed + } + + @Override + public void publish(LogRecord record) { + if (!isSupported() || !isLoggable(record)) { + return; + } + + // TODO(unnurg): pass in the throwable here since GWT.log can handle it + String msg = getFormatter().format(record); + GWT.log(msg); + } + + private boolean isSupported() { + return !GWT.isScript(); + } + +}
diff --git a/user/src/com/google/gwt/logging/client/FirebugLogHandler.java b/user/src/com/google/gwt/logging/client/FirebugLogHandler.java new file mode 100644 index 0000000..bffd9be --- /dev/null +++ b/user/src/com/google/gwt/logging/client/FirebugLogHandler.java
@@ -0,0 +1,83 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * A Handler that prints logs to window.console which is used by Firebug + * Note we are consciously using 'window' rather than '$wnd' to avoid issues + * similar to http://code.google.com/p/fbug/issues/detail?id=2914 + */ +public class FirebugLogHandler extends Handler { + + public FirebugLogHandler() { + setFormatter(new TextLogFormatter()); + setLevel(Level.ALL); + } + + @Override + public void close() { + // No action needed + } + + @Override + public void flush() { + // No action needed + } + + @Override + public void publish(LogRecord record) { + if (!isSupported() || !isLoggable(record)) { + return; + } + String msg = getFormatter().format(record); + int val = record.getLevel().intValue(); + if (val <= Level.FINE.intValue()) { + debug(msg); + } else if (val < Level.WARNING.intValue()) { + info(msg); + } else if (val < Level.SEVERE.intValue()) { + warn(msg); + } else { + error(msg); + } + } + + private native void debug(String message) /*-{ + window.console.debug(message); + }-*/; + + private native void error(String message) /*-{ + window.console.error(message); + }-*/; + + private native void info(String message) /*-{ + window.console.info(message); + }-*/; + + private native boolean isSupported() /*-{ + return !!(window.console && window.console.firebug); + }-*/; + + private native void warn(String message) /*-{ + window.console.warn(message); + }-*/; + +}
diff --git a/user/src/com/google/gwt/logging/client/HasWidgetsLogHandler.java b/user/src/com/google/gwt/logging/client/HasWidgetsLogHandler.java new file mode 100644 index 0000000..7e6d062 --- /dev/null +++ b/user/src/com/google/gwt/logging/client/HasWidgetsLogHandler.java
@@ -0,0 +1,76 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasWidgets; +import com.google.gwt.user.client.ui.Label; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * A handler which can log to any widget which extends the HasWidgets interface. + * This allows users to log to anywhere they would like in their UI - see the + * LogConfiguration class for an example. Note that the widget passed in must + * handle multiple calls to widget.add(widget) gracefully. + */ +public class HasWidgetsLogHandler extends Handler { + + private HasWidgets widgetContainer; + + public HasWidgetsLogHandler(HasWidgets container) { + this.widgetContainer = container; + setFormatter(new HtmlLogFormatter()); + setLevel(Level.ALL); + } + + public void clear() { + widgetContainer.clear(); + } + + @Override + public void close() { + // Do nothing + } + + @Override + public void flush() { + // Do nothing + } + + @Override + public void publish(LogRecord record) { + if (!isLoggable(record)) { + return; + } + Formatter formatter = getFormatter(); + String msg = formatter.format(record); + // We want to make sure that unescaped messages are not output as HTML to + // the window and the HtmlLogFormatter ensures this. If you want to write a + // new formatter, subclass HtmlLogFormatter and override the getHtmlPrefix + // and getHtmlSuffix methods. + if (formatter instanceof HtmlLogFormatter) { + widgetContainer.add(new HTML(msg)); + } else { + widgetContainer.add(new Label(msg)); + } + } +} +
diff --git a/user/src/com/google/gwt/logging/client/HtmlLogFormatter.java b/user/src/com/google/gwt/logging/client/HtmlLogFormatter.java new file mode 100644 index 0000000..c7d054f --- /dev/null +++ b/user/src/com/google/gwt/logging/client/HtmlLogFormatter.java
@@ -0,0 +1,64 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import java.util.Date; +import java.util.logging.Formatter; +import java.util.logging.LogRecord; + +/** + * Formats LogRecords into HTML. Subclasses should override the GetHtmlPrefix + * and GetHtmlSuffix methods rather than format to ensure that the message + * is properly escaped. + */ +public class HtmlLogFormatter extends Formatter { + + // TODO(unnurg): Handle the outputting of Throwables. + @Override + public String format(LogRecord event) { + StringBuilder html = new StringBuilder(getHtmlPrefix(event)); + html.append(getEscapedMessage(event)); + html.append(getHtmlSuffix(event)); + return html.toString(); + } + + protected String getHtmlPrefix(LogRecord event) { + Date date = new Date(event.getMillis()); + StringBuilder prefix = new StringBuilder(); + prefix.append("<code>"); + prefix.append(date.toString()); + prefix.append(" "); + prefix.append(event.getLoggerName()); + prefix.append("<br/>"); + prefix.append(event.getLevel().getName()); + prefix.append(": "); + return prefix.toString(); + } + + protected String getHtmlSuffix(LogRecord event) { + // TODO(unnurg): output throwables correctly + return "</code>"; + } + + // TODO(unnurg): There must be a cleaner way to do this... + private String getEscapedMessage(LogRecord event) { + String text = event.getMessage(); + text = text.replaceAll("<", "<"); + text = text.replaceAll(">", ">"); + return text; + } +}
diff --git a/user/src/com/google/gwt/logging/client/LogConfiguration.java b/user/src/com/google/gwt/logging/client/LogConfiguration.java new file mode 100644 index 0000000..fd88112 --- /dev/null +++ b/user/src/com/google/gwt/logging/client/LogConfiguration.java
@@ -0,0 +1,127 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.Window.Location; +import com.google.gwt.user.client.ui.HasWidgets; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Configures client side logging using the query params and gwt.xml settings. + */ +public class LogConfiguration implements EntryPoint { + + private interface LogConfigurationImpl { + void configureClientSideLogging(); + } + + /** + * Implementation which does nothing and compiles out if logging is disabled. + */ + private static class LogConfigurationImplNull + implements LogConfigurationImpl { + public void configureClientSideLogging() { } + } + + /** + * Implementation which is used when logging is enabled. + */ + private static class LogConfigurationImplRegular + implements LogConfigurationImpl { + + public void configureClientSideLogging() { + Logger root = Logger.getLogger(""); + setLevels(root); + setDefaultHandlers(root); + } + + private void addHandlerIfNotNull(Logger l, Handler h) { + if (!(h instanceof NullLogHandler)) { + l.addHandler(h); + } + } + + private Level parseLevel(String s) { + if (s == null) { + return null; + } + if (s.equals(Level.OFF.getName())) { + return Level.OFF; + } else if (s.equals(Level.SEVERE.getName())) { + return Level.SEVERE; + } else if (s.equals(Level.WARNING.getName())) { + return Level.WARNING; + } else if (s.equals(Level.INFO.getName())) { + return Level.INFO; + } else if (s.equals(Level.CONFIG.getName())) { + return Level.CONFIG; + } else if (s.equals(Level.FINE.getName())) { + return Level.FINE; + } else if (s.equals(Level.FINER.getName())) { + return Level.FINER; + } else if (s.equals(Level.FINEST.getName())) { + return Level.FINEST; + } else if (s.equals(Level.ALL.getName())) { + return Level.ALL; + } + return null; + } + + private void setDefaultHandlers(Logger l) { + // Add the default handlers. If users want some of these disabled, they + // will specify that in the gwt.xml file, which will replace the handler + // with an instance of NullLogHandler, effectively disabling it. + Handler console = GWT.create(ConsoleLogHandler.class); + addHandlerIfNotNull(l, console); + Handler dev = GWT.create(DevelopmentModeLogHandler.class); + addHandlerIfNotNull(l, dev); + Handler firebug = GWT.create(FirebugLogHandler.class); + addHandlerIfNotNull(l, firebug); + Handler system = GWT.create(SystemLogHandler.class); + addHandlerIfNotNull(l, system); + HasWidgets loggingWidget = GWT.create(BasicLoggingPopup.class); + if (!(loggingWidget instanceof NullLoggingPopup)) { + addHandlerIfNotNull(l, new HasWidgetsLogHandler(loggingWidget)); + } + } + + private void setLevels(Logger l) { + // try to pull the log level from the query param + Level paramLevel = parseLevel(Location.getParameter("logLevel")); + if (paramLevel != null) { + l.setLevel(paramLevel); + } else { + // if it isn't there, then pull it from the gwt.xml file + DefaultLevel defaultLevel = GWT.create(DefaultLevel.class); + l.setLevel(defaultLevel.getLevel()); + } + } + } + + private static LogConfigurationImpl impl = + GWT.create(LogConfigurationImplNull.class); + + public void onModuleLoad() { + impl.configureClientSideLogging(); + } + +}
diff --git a/user/src/com/google/gwt/logging/client/NullLogHandler.java b/user/src/com/google/gwt/logging/client/NullLogHandler.java new file mode 100644 index 0000000..af6bfee --- /dev/null +++ b/user/src/com/google/gwt/logging/client/NullLogHandler.java
@@ -0,0 +1,38 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import java.util.logging.Handler; +import java.util.logging.LogRecord; + +/** + * A Handler which does nothing. When clients disable a default log handler in + * their gwt.xml file, the handler gets replaced with this one, and is + * effectively disabled. + */ +public class NullLogHandler extends Handler { + + @Override + public void close() { } + + @Override + public void flush() { } + + @Override + public void publish(LogRecord record) { } + +}
diff --git a/user/src/com/google/gwt/logging/client/NullLoggingPopup.java b/user/src/com/google/gwt/logging/client/NullLoggingPopup.java new file mode 100644 index 0000000..e84513b --- /dev/null +++ b/user/src/com/google/gwt/logging/client/NullLoggingPopup.java
@@ -0,0 +1,42 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import com.google.gwt.user.client.ui.HasWidgets; +import com.google.gwt.user.client.ui.Widget; + +import java.util.Iterator; + +/** + * A class which can be substituted in for the BasicLoggingPopup in the + * the gwt.xml file to disable the default popup log handler. + */ +public class NullLoggingPopup implements HasWidgets { + + public void add(Widget w) { } + + public void clear() { } + + public Iterator<Widget> iterator() { + return null; + } + + public boolean remove(Widget w) { + return false; + } + +}
diff --git a/user/src/com/google/gwt/logging/client/SystemLogHandler.java b/user/src/com/google/gwt/logging/client/SystemLogHandler.java new file mode 100644 index 0000000..1a35ff2 --- /dev/null +++ b/user/src/com/google/gwt/logging/client/SystemLogHandler.java
@@ -0,0 +1,62 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import com.google.gwt.core.client.GWT; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * A Handler that prints logs to System.out or System.err + */ +public class SystemLogHandler extends Handler { + + public SystemLogHandler() { + setFormatter(new TextLogFormatter()); + setLevel(Level.ALL); + } + + @Override + public void close() { + // No action needed + } + + @Override + public void flush() { + // No action needed + } + + @Override + public void publish(LogRecord record) { + if (!isSupported() || !isLoggable(record)) { + return; + } + String msg = getFormatter().format(record); + int val = record.getLevel().intValue(); + if (val <= Level.WARNING.intValue()) { + System.out.println(msg); + } else { + System.err.println(msg); + } + } + + private boolean isSupported() { + return !GWT.isScript(); + } +}
diff --git a/user/src/com/google/gwt/logging/client/TextLogFormatter.java b/user/src/com/google/gwt/logging/client/TextLogFormatter.java new file mode 100644 index 0000000..183d5b1 --- /dev/null +++ b/user/src/com/google/gwt/logging/client/TextLogFormatter.java
@@ -0,0 +1,44 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.client; + +import java.util.Date; +import java.util.logging.Formatter; +import java.util.logging.LogRecord; + +/** + * Formats LogRecords into 2 lines of text + */ +public class TextLogFormatter extends Formatter { + + @Override + public String format(LogRecord event) { + Date date = new Date(event.getMillis()); + StringBuilder message = new StringBuilder(); + message.append(date.toString()); + message.append(" "); + message.append(event.getLoggerName()); + message.append("\n"); + message.append(event.getLevel().getName()); + message.append(": "); + message.append(event.getMessage()); + if (event.getThrown() != null) { + // TODO(unnurg): output throwables correctly + } + return message.toString(); + } +}
diff --git a/user/src/com/google/gwt/logging/impl/LevelImpl.java b/user/src/com/google/gwt/logging/impl/LevelImpl.java new file mode 100644 index 0000000..f1a8426 --- /dev/null +++ b/user/src/com/google/gwt/logging/impl/LevelImpl.java
@@ -0,0 +1,41 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.impl; + +import java.util.logging.Level; + +/** + * Interface for the implementation of Level. We use a LevelImplNull to ensure + * that logging code compiles out when logging is disabled, and a + * LevelImplRegular to provide normal functionality when logging is enabled. + */ +public interface LevelImpl { + Level all(); + Level config(); + Level fine(); + Level finer(); + Level finest(); + String getName(); + Level info(); + int intValue(); + Level off(); + void setName(String newName); + void setValue(int newValue); + Level severe(); + String toString(); + Level warning(); +}
diff --git a/user/src/com/google/gwt/logging/impl/LevelImplNull.java b/user/src/com/google/gwt/logging/impl/LevelImplNull.java new file mode 100644 index 0000000..c202711 --- /dev/null +++ b/user/src/com/google/gwt/logging/impl/LevelImplNull.java
@@ -0,0 +1,77 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.impl; + +import java.util.logging.Level; + +/** + * Null implementation for the Level class which ensures that calls to Level + * compile out when logging is disabled. + */ +public class LevelImplNull implements LevelImpl { + + public Level all() { + return null; + } + + public Level config() { + return null; + } + + public Level fine() { + return null; + } + + public Level finer() { + return null; + } + + public Level finest() { + return null; + } + + public String getName() { + return null; + } + + public Level info() { + return null; + } + + public int intValue() { + return 0; + } + + public Level off() { + return null; + } + + public void setName(String newName) { + } + + public void setValue(int newValue) { + } + + public Level severe() { + return null; + } + + public Level warning() { + return null; + } + +}
diff --git a/user/src/com/google/gwt/logging/impl/LevelImplRegular.java b/user/src/com/google/gwt/logging/impl/LevelImplRegular.java new file mode 100644 index 0000000..f2a8e30 --- /dev/null +++ b/user/src/com/google/gwt/logging/impl/LevelImplRegular.java
@@ -0,0 +1,116 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.impl; + +import java.util.logging.Level; + +/** + * Implementation for the Level class when logging is enabled. + */ +public class LevelImplRegular implements LevelImpl { + + /** + * Since the Impl class is in a different package than the Level class, we + * need to work around the fact that the Impl class cannot access the + * protected Level constructor. + */ + private static class LevelWithExposedConstructor extends Level { + public LevelWithExposedConstructor(String name, int value) { + super(name, value); + } + } + + private static Level ALL = + new LevelWithExposedConstructor("ALL", Integer.MIN_VALUE); + private static Level CONFIG = + new LevelWithExposedConstructor("CONFIG", 700); + private static Level FINE = + new LevelWithExposedConstructor("FINE", 500); + private static Level FINER = + new LevelWithExposedConstructor("FINER", 400); + private static Level FINEST = + new LevelWithExposedConstructor("FINEST", 300); + private static Level INFO = + new LevelWithExposedConstructor("INFO", 800); + private static Level OFF = + new LevelWithExposedConstructor("OFF", Integer.MAX_VALUE); + private static Level SEVERE = + new LevelWithExposedConstructor("SEVERE", 1000); + private static Level WARNING = + new LevelWithExposedConstructor("WARNING", 900); + + private String name; + private int value; + + public LevelImplRegular() { } + + public Level all() { + return LevelImplRegular.ALL; + } + + public Level config() { + return LevelImplRegular.CONFIG; + } + + public Level fine() { + return LevelImplRegular.FINE; + } + + public Level finer() { + return LevelImplRegular.FINER; + } + + public Level finest() { + return LevelImplRegular.FINEST; + } + + public String getName() { + return name; + } + + public Level info() { + return LevelImplRegular.INFO; + } + + public int intValue() { + return value; + } + + public Level off() { + return LevelImplRegular.OFF; + } + + public void setName(String newName) { + name = newName; + } + + public void setValue(int newValue) { + value = newValue; + } + + public Level severe() { + return LevelImplRegular.SEVERE; + } + + public String toString() { + return getName(); + } + + public Level warning() { + return LevelImplRegular.WARNING; + } +}
diff --git a/user/src/com/google/gwt/logging/impl/LoggerImpl.java b/user/src/com/google/gwt/logging/impl/LoggerImpl.java new file mode 100644 index 0000000..edb15dd --- /dev/null +++ b/user/src/com/google/gwt/logging/impl/LoggerImpl.java
@@ -0,0 +1,59 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.impl; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * Interface for the implementation of Logger. We use a LoggerImplNull to ensure + * that logging code compiles out when logging is disabled, and a + * LoggerImplRegular to provide normal functionality when logging is enabled. + */ +public interface LoggerImpl { + void addHandler(Handler handler); + void config(String msg); + void fine(String msg); + void finer(String msg); + void finest(String msg); + + /** + * Get the handlers attached to this logger. + * @return the array of handlers, or null if there are no handlers + */ + Handler[] getHandlers(); + + Level getLevel(); + Logger getLoggerHelper(String name); + String getName(); + Logger getParent(); + boolean getUseParentHandlers(); + void info(String msg); + boolean isLoggable(Level messageLevel); + void log(Level level, String msg); + void log(Level level, String msg, Throwable thrown); + void log(LogRecord record); + void removeHandler(Handler handler); + void setLevel(Level newLevel); + void setName(String newName); + void setParent(Logger newParent); + void setUseParentHandlers(boolean newUseParentHandlers); + void severe(String msg); + void warning(String msg); +}
diff --git a/user/src/com/google/gwt/logging/impl/LoggerImplNull.java b/user/src/com/google/gwt/logging/impl/LoggerImplNull.java new file mode 100644 index 0000000..0f76c87 --- /dev/null +++ b/user/src/com/google/gwt/logging/impl/LoggerImplNull.java
@@ -0,0 +1,126 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.impl; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * Null implementation for the Logger class which ensures that calls to Logger + * compile out when logging is disabled. + */ +public class LoggerImplNull implements LoggerImpl { + + public void addHandler(Handler handler) { + // Do nothing + } + + public void config(String msg) { + // Do nothing + } + + public void fine(String msg) { + // Do nothing + } + + public void finer(String msg) { + // Do nothing + } + + public void finest(String msg) { + // Do nothing + } + + public Handler[] getHandlers() { + return null; + } + + public Level getLevel() { + return null; + } + + public Logger getLoggerHelper(String name) { + // We need to return an actual logger here rather than null, because client + // code will make calls like Logger.getLogger().log(), and we don't want a + // NullPointerException. Since a LoggerImplNull will be behind this logger + // that we are returning, that will ensure that the log() call does nothing + // and gets compiled out. + return new LoggerWithExposedConstructor(""); + } + + public String getName() { + return ""; + } + + public Logger getParent() { + return null; + } + + public boolean getUseParentHandlers() { + return false; + } + + public void info(String msg) { + // Do nothing + } + + public boolean isLoggable(Level messageLevel) { + return false; + } + + public void log(Level level, String msg) { + // Do nothing + } + + public void log(Level level, String msg, Throwable thrown) { + // Do nothing + } + + public void log(LogRecord record) { + // Do nothing + } + + public void removeHandler(Handler handler) { + // Do nothing + } + + public void setLevel(Level newLevel) { + // Do nothing + } + + public void setName(String newName) { + // Do nothing + } + + public void setParent(Logger newParent) { + // Do nothing + } + + public void setUseParentHandlers(boolean newUseParentHandlers) { + // Do nothing + } + + public void severe(String msg) { + // Do nothing + } + + public void warning(String msg) { + // Do nothing + } +}
diff --git a/user/src/com/google/gwt/logging/impl/LoggerImplRegular.java b/user/src/com/google/gwt/logging/impl/LoggerImplRegular.java new file mode 100644 index 0000000..73a4ba7 --- /dev/null +++ b/user/src/com/google/gwt/logging/impl/LoggerImplRegular.java
@@ -0,0 +1,166 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * Implementation for the Logger class when logging is enabled. + */ +public class LoggerImplRegular implements LoggerImpl { + private List<Handler> handlers; + private Level level = null; + private String name; + private Logger parent; // Should never be null except in the RootLogger + private boolean useParentHandlers; + + public LoggerImplRegular() { + this.useParentHandlers = true; + handlers = new ArrayList<Handler>(); + } + + public void addHandler(Handler handler) { + handlers.add(handler); + } + + public void config(String msg) { + log(Level.CONFIG, msg); + } + + public void fine(String msg) { + log(Level.FINE, msg); + } + + public void finer(String msg) { + log(Level.FINER, msg); + } + + public void finest(String msg) { + log(Level.FINEST, msg); + } + + public Handler[] getHandlers() { + if (handlers.size() > 0) { + return (Handler[]) handlers.toArray(); + } + return null; + } + + public Level getLevel() { + if (level != null) { + return level; + } + return getParent().getLevel(); + } + + public Logger getLoggerHelper(String name) { + // Ideally, we'd just return LogManager.getLogManager.getOrAddLogger(name) + // here, since the code is basically the same, except that code gets to call + // addLoggerWithoutDuplicationChecking, which makes it somewhat more + // efficient. However, that means adding a public method to LogManager which + // is not in the API which is frowned upon. + LogManager manager = LogManager.getLogManager(); + Logger logger = manager.getLogger(name); + if (logger == null) { + Logger newLogger = new LoggerWithExposedConstructor(name); + manager.addLogger(newLogger); + return newLogger; + } + return logger; + } + + public String getName() { + return name; + } + + public Logger getParent() { + return parent; + } + + public boolean getUseParentHandlers() { + return useParentHandlers; + } + + public void info(String msg) { + log(Level.INFO, msg); + } + + public boolean isLoggable(Level messageLevel) { + return getLevel().intValue() <= messageLevel.intValue(); + } + + public void log(Level level, String msg) { + log(level, msg, null); + } + + public void log(Level level, String msg, Throwable thrown) { + if (isLoggable(level)) { + LogRecord record = new LogRecord(level, msg); + record.setThrown(thrown); + record.setLoggerName(getName()); + log(record); + } + } + + public void log(LogRecord record) { + if (isLoggable(record.getLevel())) { + for (Handler h : handlers) { + h.publish(record); + } + if (useParentHandlers && parent != null) { + parent.log(record); + } + } + } + + public void removeHandler(Handler handler) { + handlers.remove(handler); + } + + public void setLevel(Level newLevel) { + level = newLevel; + } + + public void setName(String newName) { + name = newName; + } + + public void setParent(Logger newParent) { + if (newParent != null) { + parent = newParent; + } + } + + public void setUseParentHandlers(boolean newUseParentHandlers) { + useParentHandlers = newUseParentHandlers; + } + + public void severe(String msg) { + log(Level.SEVERE, msg); + } + + public void warning(String msg) { + log(Level.WARNING, msg); + } + +}
diff --git a/user/src/com/google/gwt/logging/impl/LoggerWithExposedConstructor.java b/user/src/com/google/gwt/logging/impl/LoggerWithExposedConstructor.java new file mode 100644 index 0000000..fe20f06 --- /dev/null +++ b/user/src/com/google/gwt/logging/impl/LoggerWithExposedConstructor.java
@@ -0,0 +1,32 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.gwt.logging.impl; + +import java.util.logging.Logger; + +/** + * Since the Impl classes are in a different package than the classes they + * implement, they cannot use the protected Logger constructor. This subclass + * of Logger, which just explses the constructor, gets around that, and it's + * protected constructor is only available in the impl package, so clients + * cannot use it. + */ +public class LoggerWithExposedConstructor extends Logger { + protected LoggerWithExposedConstructor(String name) { + super(name, null); + } +}
diff --git a/user/super/com/google/gwt/emul/Emulation.gwt.xml b/user/super/com/google/gwt/emul/Emulation.gwt.xml index d74ae89..a6d85c2 100644 --- a/user/super/com/google/gwt/emul/Emulation.gwt.xml +++ b/user/super/com/google/gwt/emul/Emulation.gwt.xml
@@ -15,6 +15,8 @@ <!-- A JavaScript-based emulation of the Java Runtime library. --> <!-- Do not inherit this module directly; inherit com.google.gwt.core.Core. --> <module> + <inherits name="com.google.gwt.logging.LogImpl"/> + <replace-with class="com.google.gwt.core.client.impl.StringBufferImplArray"> <when-type-is class="com.google.gwt.core.client.impl.StringBufferImpl"/> </replace-with>
diff --git a/user/super/com/google/gwt/emul/java/util/logging/Formatter.java b/user/super/com/google/gwt/emul/java/util/logging/Formatter.java new file mode 100644 index 0000000..b0ce949 --- /dev/null +++ b/user/super/com/google/gwt/emul/java/util/logging/Formatter.java
@@ -0,0 +1,35 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package java.util.logging; + +/** + * An emulation of the java.util.logging.Formatter class. See + * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/Formatter.html"> + * The Java API doc for details</a> + */ +public abstract class Formatter { + public abstract String format(LogRecord record); + + public String formatMessage(LogRecord record) { + return format(record); + } + + /* Not Implemented */ + // public String getHead(Handler h) {} + // public String getTail(Handler h) {} + +}
diff --git a/user/super/com/google/gwt/emul/java/util/logging/Handler.java b/user/super/com/google/gwt/emul/java/util/logging/Handler.java new file mode 100644 index 0000000..3b89c3c --- /dev/null +++ b/user/super/com/google/gwt/emul/java/util/logging/Handler.java
@@ -0,0 +1,64 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package java.util.logging; + +/** + * An emulation of the java.util.logging.Handler class. See + * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/Handler.html"> + * The Java API doc for details</a> + */ +public abstract class Handler { + private Formatter formatter; + private Level level; + + public abstract void close(); + public abstract void flush(); + + public Formatter getFormatter() { + return formatter; + } + + public Level getLevel() { + if (level != null) { + return level; + } + return Level.ALL; + } + + public boolean isLoggable(LogRecord record) { + return getLevel().intValue() <= record.getLevel().intValue(); + } + + public abstract void publish(LogRecord record); + + public void setFormatter(Formatter newFormatter) { + formatter = newFormatter; + } + + public void setLevel(Level newLevel) { + level = newLevel; + } + + /* Not Implemented */ + // public String getEncoding() {} + // public ErrorManager getErrorManager() {} + // public Filter getFilter() {} + // public protected void reportError(String msg, Exception ex, int code) {} + // public void setEncoding(String encoding) {} + // public void setErrorManager(ErrorManager em) {} + // public void setFilter(Filter newFilter) {} +}
diff --git a/user/super/com/google/gwt/emul/java/util/logging/Level.java b/user/super/com/google/gwt/emul/java/util/logging/Level.java new file mode 100644 index 0000000..478bbbc --- /dev/null +++ b/user/super/com/google/gwt/emul/java/util/logging/Level.java
@@ -0,0 +1,71 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package java.util.logging; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.logging.impl.LevelImpl; +import com.google.gwt.logging.impl.LevelImplNull; + +import java.io.Serializable; + +/** + * An emulation of the java.util.logging.Level class. See + * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/Level.html"> + * The Java API doc for details</a> + */ +public class Level implements Serializable { + private static LevelImpl staticImpl = GWT.create(LevelImplNull.class); + public static Level ALL = staticImpl.all(); + public static Level CONFIG = staticImpl.config(); + public static Level FINE = staticImpl.fine(); + public static Level FINER = staticImpl.finer(); + public static Level FINEST = staticImpl.finest(); + public static Level INFO = staticImpl.info(); + public static Level OFF = staticImpl.off(); + public static Level SEVERE = staticImpl.severe(); + public static Level WARNING = staticImpl.warning(); + + private LevelImpl impl; + + protected Level(String name, int value) { + impl = GWT.create(LevelImplNull.class); + impl.setName(name); + impl.setValue(value); + } + + public String getName() { + return impl.getName(); + } + + public int intValue() { + return impl.intValue(); + } + + @Override + public String toString() { + return impl.toString(); + } + + /* Not Implemented */ + // public static Level parse(String name) {} + // public boolean equals(Object ox) {} + // protected Level(String name, int value, String resourceBundleName) {} + // public String getLocalizedName() {} + // public String getResourceBundleName() {} + // public int hashCode() {} + +}
diff --git a/user/super/com/google/gwt/emul/java/util/logging/LogManager.java b/user/super/com/google/gwt/emul/java/util/logging/LogManager.java new file mode 100644 index 0000000..2dfec3f --- /dev/null +++ b/user/super/com/google/gwt/emul/java/util/logging/LogManager.java
@@ -0,0 +1,108 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package java.util.logging; + +import java.util.HashMap; + +/** + * An emulation of the java.util.logging.LogManager class. See + * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/LogManger.html"> + * The Java API doc for details</a> + */ +public class LogManager { + /** + * Since the Logger constructor is protected, the LogManager cannot create + * one directly, so we create a RootLogger which has an exposed constructor. + */ + private class RootLogger extends Logger { + public RootLogger() { + super("", null); + setLevel(Level.ALL); + } + } + + private static LogManager singleton; + + public static LogManager getLogManager() { + if (singleton == null) { + singleton = new LogManager(); + } + return singleton; + } + + private HashMap<String, Logger> loggerList; + private Logger rootLogger; + + protected LogManager() { + loggerList = new HashMap<String, Logger>(); + rootLogger = new RootLogger(); + loggerList.put("", rootLogger); + } + + public boolean addLogger(Logger logger) { + if (getLogger(logger.getName()) != null) { + return false; + } + addLoggerWithoutDuplicationChecking(logger); + return true; + } + + public Logger getLogger(String name) { + return loggerList.get(name); + } + + /** + * Helper function to add a logger when we have already determined that it + * does not exist. When we add a logger, we recursively add all of it's + * ancestors. Since loggers do not get removed, logger creation is cheap, + * and there are not usually too many loggers in an ancestry chain, + * this is a simple way to ensure that the parent/child relationships are + * always correctly set up. + */ + private void addLoggerWithoutDuplicationChecking(Logger logger) { + String name = logger.getName(); + String parentName = name.substring(0, Math.max(0, name.lastIndexOf('.'))); + Logger parent = getOrAddLogger(parentName); + loggerList.put(logger.getName(), logger); + logger.setParent(parent); + } + + /** + * Helper function to create a logger if it does not exist since the public + * APIs for getLogger and addLogger make it difficult to use those functions + * for this. + */ + private Logger getOrAddLogger(String name) { + Logger logger = getLogger(name); + if (logger == null) { + Logger newLogger = new Logger(name, null); + addLoggerWithoutDuplicationChecking(newLogger); + return newLogger; + } + return logger; + } + + /* Not Implemented */ + // public void addPropertyChangeListener(PropertyChangeListener l) {} + // public void checkAccess() {} + // public Enumeration getLoggerNames() {} + // public String getProperty(String name) {} + // public void readConfiguration() {} + // public void readConfiguration(InputStream ins) {} + // public void removePropertyChangeListener(PropertyChangeListener l) {} + // public void reset() {} +}
diff --git a/user/super/com/google/gwt/emul/java/util/logging/LogRecord.java b/user/super/com/google/gwt/emul/java/util/logging/LogRecord.java new file mode 100644 index 0000000..ef90fdc --- /dev/null +++ b/user/super/com/google/gwt/emul/java/util/logging/LogRecord.java
@@ -0,0 +1,99 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package java.util.logging; + +import java.io.Serializable; +import java.util.Date; + +/** + * An emulation of the java.util.logging.LogRecord class. See + * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/LogRecord.html"> + * The Java API doc for details</a> + */ +public class LogRecord implements Serializable { + private Level level; + private String loggerName = ""; + private String msg; + private Throwable thrown = null; + private Date timestamp; + + public LogRecord(Level level, String msg) { + this.level = level; + this.msg = msg; + timestamp = new Date(); + } + + protected LogRecord() { + // for serialization + } + + public Level getLevel() { + return level; + } + + public String getLoggerName() { + return loggerName; + } + + public String getMessage() { + return msg; + } + + public long getMillis() { + return timestamp.getTime(); + } + + public Throwable getThrown() { + return thrown; + } + + public void setLevel(Level newLevel) { + level = newLevel; + } + + public void setLoggerName(String newName) { + loggerName = newName; + } + + public void setMessage(String newMessage) { + msg = newMessage; + } + + public void setMillis(long millis) { + timestamp.setTime(millis); + } + + public void setThrown(Throwable newThrown) { + thrown = newThrown; + } + + /* Not Implemented */ + // public Object[] getParameters() {} + // public ResourceBundle getResourceBundle() {} + // public String getResourceBundleName() {} + // public long getSequenceNumber() {} + // public String getSourceClassName() {} + // public String getSourceMethodName() {} + // public int getThreadID() {} + // public void setParameters(Object[] parameters) {} + // public void setResourceBundle(ResourceBundle bundle) {} + // public void setResourceBundleName(String name) {} + // public void setSequenceNumber(long seq) {} + // public void setSourceClassName(String sourceClassName) {} + // public void setSourceMethodName(String sourceMethodName) {} + // public void setThreadID(int threadID) {} +}
diff --git a/user/super/com/google/gwt/emul/java/util/logging/Logger.java b/user/super/com/google/gwt/emul/java/util/logging/Logger.java new file mode 100644 index 0000000..55fdb79 --- /dev/null +++ b/user/super/com/google/gwt/emul/java/util/logging/Logger.java
@@ -0,0 +1,149 @@ +/* + * Copyright 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package java.util.logging; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.logging.impl.LoggerImpl; +import com.google.gwt.logging.impl.LoggerImplNull; + +/** + * An emulation of the java.util.logging.Logger class. See + * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/Logger.html"> + * The Java API doc for details</a> + */ +public class Logger { + private static LoggerImpl staticImpl = GWT.create(LoggerImplNull.class); + + public static Logger getLogger(String name) { + return staticImpl.getLoggerHelper(name); + } + + private LoggerImpl impl; + + protected Logger(String name, String resourceName) { + impl = GWT.create(LoggerImplNull.class); + impl.setName(name); + } + + public void addHandler(Handler handler) { + impl.addHandler(handler); + } + + public void config(String msg) { + impl.config(msg); + } + + public void fine(String msg) { + impl.fine(msg); + } + + public void finer(String msg) { + impl.finer(msg); + } + + public void finest(String msg) { + impl.finest(msg); + } + + public Handler[] getHandlers() { + return impl.getHandlers(); + } + + public Level getLevel() { + return impl.getLevel(); + } + + public String getName() { + return impl.getName(); + } + + public Logger getParent() { + return impl.getParent(); + } + + public boolean getUseParentHandlers() { + return impl.getUseParentHandlers(); + } + + public void info(String msg) { + impl.info(msg); + } + + public boolean isLoggable(Level messageLevel) { + return impl.isLoggable(messageLevel); + } + + public void log(Level level, String msg) { + impl.log(level, msg); + } + + public void log(Level level, String msg, Throwable thrown) { + impl.log(level, msg, thrown); + } + + public void log(LogRecord record) { + impl.log(record); + } + + public void removeHandler(Handler handler) { + impl.removeHandler(handler); + } + + public void setLevel(Level newLevel) { + impl.setLevel(newLevel); + } + + public void setParent(Logger newParent) { + impl.setParent(newParent); + } + + public void setUseParentHandlers(boolean newUseParentHandlers) { + impl.setUseParentHandlers(newUseParentHandlers); + } + + public void severe(String msg) { + impl.severe(msg); + } + + public void warning(String msg) { + impl.warning(msg); + } + + /* Not Implemented */ + // public static Logger getAnonymousLogger() { + // public static Logger getAnonymousLogger(String resourceBundleName) {} + // public Filter getFilter() {} + // public static Logger getLogger(String name, String resourceBundleName) {} + // public ResourceBundle getResourceBundle() {} + // public String getResourceBundleName() {} + // public void setFilter(Filter newFilter) {} + // public void entering(String sourceClass, String sourceMethod) {} + // public void entering(String sourceClass, String sourceMethod, Object param1) {} + // public void entering(String sourceClass, String sourceMethod, Object[] params) {} + // public void exiting(String sourceClass, String sourceMethod, Object result) {} + // public void exiting(String sourceClass, String sourceMethod) {} + // public void log(Level level, String msg, Object param1) {} + // public void log(Level level, String msg, Object[] params) {} + // public void logp(Level level, String sourceClass, String sourceMethod, String msg) {} + // public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object param1) {} + // public void logp(Level level, String sourceClass, String sourceMethod, String msg, Object[] params) {} + // public void logp(Level level, String sourceClass, String sourceMethod, String msg, Throwable thrown) {} + // public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg) {} + // public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg, Object param1) {} + // public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg, Object[] params) {} + // public void logrb(Level level, String sourceClass, String sourceMethod, String bundleName, String msg, Throwable thrown) {} + // public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {} +} \ No newline at end of file