No effective change - change newline char

This commit is contained in:
rbygrave
2015-05-09 01:09:32 +12:00
parent 726d3a0c38
commit 4143c0de26
41 changed files with 6895 additions and 6895 deletions
@@ -1,79 +1,79 @@
package com.avaje.ebeaninternal.server.lib;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Daemon based ScheduleThreadPool.
* <p>
* Uses Daemon threads and hooks into shutdown event.
* </p>
*
* @author rbygrave
*/
public final class DaemonScheduleThreadPool extends ScheduledThreadPoolExecutor {
private static final Logger logger = LoggerFactory.getLogger(DaemonScheduleThreadPool.class);
private final String namePrefix;
private int shutdownWaitSeconds;
/**
* Construct the DaemonScheduleThreadPool.
*/
public DaemonScheduleThreadPool(int coreSize, int shutdownWaitSeconds, String namePrefix) {
super(coreSize, new DaemonThreadFactory(namePrefix));
this.namePrefix = namePrefix;
this.shutdownWaitSeconds = shutdownWaitSeconds;
}
/**
* Register a shutdown hook with the JVM Runtime.
*/
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
}
/**
* Shutdown this thread pool nicely if possible.
* <p>
* This will wait a maximum of 20 seconds before terminating any threads still
* working.
* </p>
*/
public void shutdown() {
synchronized (this) {
if (super.isShutdown()) {
logger.debug("DaemonScheduleThreadPool {} already shut down", namePrefix);
return;
}
try {
logger.debug("DaemonScheduleThreadPool {} shutting down...", namePrefix);
super.shutdown();
if (!super.awaitTermination(shutdownWaitSeconds, TimeUnit.SECONDS)) {
logger.info("DaemonScheduleThreadPool shut down timeout exceeded. Terminating running threads.");
super.shutdownNow();
}
} catch (Exception e) {
logger.error("Error during shutdown of " + namePrefix, e);
e.printStackTrace();
}
}
}
/**
* Fired by the JVM Runtime shutdown.
*/
private class ShutdownHook extends Thread {
@Override
public void run() {
shutdown();
}
};
}
package com.avaje.ebeaninternal.server.lib;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Daemon based ScheduleThreadPool.
* <p>
* Uses Daemon threads and hooks into shutdown event.
* </p>
*
* @author rbygrave
*/
public final class DaemonScheduleThreadPool extends ScheduledThreadPoolExecutor {
private static final Logger logger = LoggerFactory.getLogger(DaemonScheduleThreadPool.class);
private final String namePrefix;
private int shutdownWaitSeconds;
/**
* Construct the DaemonScheduleThreadPool.
*/
public DaemonScheduleThreadPool(int coreSize, int shutdownWaitSeconds, String namePrefix) {
super(coreSize, new DaemonThreadFactory(namePrefix));
this.namePrefix = namePrefix;
this.shutdownWaitSeconds = shutdownWaitSeconds;
}
/**
* Register a shutdown hook with the JVM Runtime.
*/
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
}
/**
* Shutdown this thread pool nicely if possible.
* <p>
* This will wait a maximum of 20 seconds before terminating any threads still
* working.
* </p>
*/
public void shutdown() {
synchronized (this) {
if (super.isShutdown()) {
logger.debug("DaemonScheduleThreadPool {} already shut down", namePrefix);
return;
}
try {
logger.debug("DaemonScheduleThreadPool {} shutting down...", namePrefix);
super.shutdown();
if (!super.awaitTermination(shutdownWaitSeconds, TimeUnit.SECONDS)) {
logger.info("DaemonScheduleThreadPool shut down timeout exceeded. Terminating running threads.");
super.shutdownNow();
}
} catch (Exception e) {
logger.error("Error during shutdown of " + namePrefix, e);
e.printStackTrace();
}
}
}
/**
* Fired by the JVM Runtime shutdown.
*/
private class ShutdownHook extends Thread {
@Override
public void run() {
shutdown();
}
};
}
@@ -1,49 +1,49 @@
package com.avaje.ebeaninternal.server.lib;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* ThreadFactory for Daemon threads.
* <p>
* Daemon threads do not stop a JVM stopping. If an application only has Daemon
* threads left it will shutdown.
* </p>
* <p>
* In using Daemon threads you need to either not care about being interrupted
* on shutdown or register with the JVM shutdown hook to perform a nice shutdown
* of the daemon threads etc.
* </p>
*
* @author rbygrave
*/
public class DaemonThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public DaemonThreadFactory(String namePrefix) {
SecurityManager s = System.getSecurityManager();
this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
this.namePrefix = namePrefix != null ? namePrefix : "pool-" + poolNumber.getAndIncrement() + "-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
t.setDaemon(true);
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
package com.avaje.ebeaninternal.server.lib;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* ThreadFactory for Daemon threads.
* <p>
* Daemon threads do not stop a JVM stopping. If an application only has Daemon
* threads left it will shutdown.
* </p>
* <p>
* In using Daemon threads you need to either not care about being interrupted
* on shutdown or register with the JVM shutdown hook to perform a nice shutdown
* of the daemon threads etc.
* </p>
*
* @author rbygrave
*/
public class DaemonThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public DaemonThreadFactory(String namePrefix) {
SecurityManager s = System.getSecurityManager();
this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
this.namePrefix = namePrefix != null ? namePrefix : "pool-" + poolNumber.getAndIncrement() + "-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
t.setDaemon(true);
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
}
@@ -1,86 +1,86 @@
package com.avaje.ebeaninternal.server.lib;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Thread Pool based on Daemon threads.
*
* @author rbygrave
*/
public final class DaemonThreadPool extends ThreadPoolExecutor {
private static final Logger logger = LoggerFactory.getLogger(DaemonThreadPool.class);
private final String namePrefix;
private final int shutdownWaitSeconds;
/**
* Construct the DaemonThreadPool.
*
* @param coreSize
* the core size of the thread pool.
* @param keepAliveSecs
* the time in seconds idle threads are keep alive
* @param shutdownWaitSeconds
* the time in seconds allowed for the pool to shutdown nicely. After
* this the pool is forced to shutdown.
*/
public DaemonThreadPool(int coreSize, int maximumPoolSize, long keepAliveSecs, int shutdownWaitSeconds, String namePrefix) {
super(coreSize, maximumPoolSize, keepAliveSecs, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DaemonThreadFactory(namePrefix));
allowCoreThreadTimeOut(true);
this.shutdownWaitSeconds = shutdownWaitSeconds;
this.namePrefix = namePrefix;
}
/**
* Register a shutdown hook with the JVM Runtime.
*/
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
}
/**
* Shutdown this thread pool nicely if possible.
* <p>
* This will wait a maximum of 20 seconds before terminating any threads still
* working.
* </p>
*/
public void shutdown() {
synchronized (this) {
if (super.isShutdown()) {
logger.debug("DaemonThreadPool[" + namePrefix + "] already shut down");
return;
}
try {
logger.debug("DaemonThreadPool[" + namePrefix + "] shutting down...");
super.shutdown();
if (!super.awaitTermination(shutdownWaitSeconds, TimeUnit.SECONDS)) {
logger.info("DaemonThreadPool[" + namePrefix+ "] shut down timeout exceeded. Terminating running threads.");
super.shutdownNow();
}
} catch (Exception e) {
logger.error("Error during shutdown of DaemonThreadPool[" + namePrefix + "]", e);
e.printStackTrace();
}
}
}
/**
* Fired by the JVM Runtime shutdown.
*/
private class ShutdownHook extends Thread {
@Override
public void run() {
shutdown();
}
};
}
package com.avaje.ebeaninternal.server.lib;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Thread Pool based on Daemon threads.
*
* @author rbygrave
*/
public final class DaemonThreadPool extends ThreadPoolExecutor {
private static final Logger logger = LoggerFactory.getLogger(DaemonThreadPool.class);
private final String namePrefix;
private final int shutdownWaitSeconds;
/**
* Construct the DaemonThreadPool.
*
* @param coreSize
* the core size of the thread pool.
* @param keepAliveSecs
* the time in seconds idle threads are keep alive
* @param shutdownWaitSeconds
* the time in seconds allowed for the pool to shutdown nicely. After
* this the pool is forced to shutdown.
*/
public DaemonThreadPool(int coreSize, int maximumPoolSize, long keepAliveSecs, int shutdownWaitSeconds, String namePrefix) {
super(coreSize, maximumPoolSize, keepAliveSecs, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DaemonThreadFactory(namePrefix));
allowCoreThreadTimeOut(true);
this.shutdownWaitSeconds = shutdownWaitSeconds;
this.namePrefix = namePrefix;
}
/**
* Register a shutdown hook with the JVM Runtime.
*/
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
}
/**
* Shutdown this thread pool nicely if possible.
* <p>
* This will wait a maximum of 20 seconds before terminating any threads still
* working.
* </p>
*/
public void shutdown() {
synchronized (this) {
if (super.isShutdown()) {
logger.debug("DaemonThreadPool[" + namePrefix + "] already shut down");
return;
}
try {
logger.debug("DaemonThreadPool[" + namePrefix + "] shutting down...");
super.shutdown();
if (!super.awaitTermination(shutdownWaitSeconds, TimeUnit.SECONDS)) {
logger.info("DaemonThreadPool[" + namePrefix+ "] shut down timeout exceeded. Terminating running threads.");
super.shutdownNow();
}
} catch (Exception e) {
logger.error("Error during shutdown of DaemonThreadPool[" + namePrefix + "]", e);
e.printStackTrace();
}
}
}
/**
* Fired by the JVM Runtime shutdown.
*/
private class ShutdownHook extends Thread {
@Override
public void run() {
shutdown();
}
};
}
@@ -1,22 +1,22 @@
package com.avaje.ebeaninternal.server.lib;
/**
* This is the ShutdownHook that gets added to Runtime.
* It will try to shutdown the system cleanly when the JVM exits.
* It is best to add your own shutdown hooks to StartStop.
*/
class ShutdownHook extends Thread {
ShutdownHook() {
}
/**
* Fired by the JVM Runtime on shutdown.
*/
public void run() {
ShutdownManager.shutdown();
}
};
package com.avaje.ebeaninternal.server.lib;
/**
* This is the ShutdownHook that gets added to Runtime.
* It will try to shutdown the system cleanly when the JVM exits.
* It is best to add your own shutdown hooks to StartStop.
*/
class ShutdownHook extends Thread {
ShutdownHook() {
}
/**
* Fired by the JVM Runtime on shutdown.
*/
public void run() {
ShutdownManager.shutdown();
}
};
@@ -1,187 +1,187 @@
package com.avaje.ebeaninternal.server.lib;
import com.avaje.ebean.common.SpiContainer;
import com.avaje.ebeaninternal.api.ClassUtil;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* Manages the shutdown of the JVM Runtime.
* <p>
* Makes sure all the resources are shutdown properly and in order.
* </p>
*/
public final class ShutdownManager {
private static final Logger logger = LoggerFactory.getLogger(ShutdownManager.class);
static final List<SpiEbeanServer> servers = new ArrayList<SpiEbeanServer>();
static final ShutdownHook shutdownHook = new ShutdownHook();
static boolean stopping;
static SpiContainer container;
static {
// Register the Shutdown hook
registerShutdownHook();
}
/**
* Disallow construction.
*/
private ShutdownManager() {
}
public static void registerContainer(SpiContainer ebeanContainer){
container = ebeanContainer;
}
/**
* Make sure the ShutdownManager is activated.
*/
public static void touch() {
// Do nothing
}
/**
* Return true if the system is in the process of stopping.
*/
public static boolean isStopping() {
synchronized (servers) {
return stopping;
}
}
/**
* Deregister the Shutdown hook.
* <p>
* For running in a Servlet Container a redeploy will cause a shutdown, and
* for that case we need to make sure the shutdown hook is deregistered.
* </p>
*/
protected static void deregisterShutdownHook() {
synchronized (servers) {
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
}
}
}
/**
* Register the shutdown hook with the Runtime.
*/
protected static void registerShutdownHook() {
synchronized (servers) {
try {
Runtime.getRuntime().addShutdownHook(shutdownHook);
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
}
}
}
/**
* Shutdown gracefully cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook.
* </p>
*/
public static void shutdown() {
synchronized (servers) {
if (stopping) {
// Already run shutdown...
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Shutting down");
}
stopping = true;
deregisterShutdownHook();
String shutdownRunner = System.getProperty("ebean.shutdown.runnable");
if (shutdownRunner != null) {
try {
// A custom runnable executed at the start of shutdown
Runnable r = (Runnable) ClassUtil.newInstance(shutdownRunner);
r.run();
} catch (Exception e) {
logger.error("Error running custom shutdown runnable", e);
}
}
if (container != null) {
// shutdown cluster networking if active
container.shutdown();
}
// shutdown any registered servers that have not
// already been shutdown manually
for (SpiEbeanServer server : servers) {
try {
server.shutdownManaged();
} catch (Exception ex) {
logger.error("Error executing shutdown runnable", ex);
ex.printStackTrace();
}
}
if ("true".equalsIgnoreCase(System.getProperty("ebean.datasource.deregisterAllDrivers", "false"))) {
deregisterAllJdbcDrivers();
}
}
}
private static void deregisterAllJdbcDrivers() {
// This manually deregisters all JDBC drivers
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
logger.info("Deregistering jdbc driver: "+driver);
DriverManager.deregisterDriver(driver);
} catch (SQLException e) {
logger.error("Error deregistering driver "+driver, e);
}
}
}
/**
* Register an ebeanServer to be shutdown when the JVM is shutdown.
*/
public static void registerEbeanServer(SpiEbeanServer server) {
synchronized (servers) {
servers.add(server);
}
}
/**
* Deregister an ebeanServer.
* <p>
* This is done when the ebeanServer is shutdown manually.
* </p>
*/
public static void unregisterEbeanServer(SpiEbeanServer server) {
synchronized (servers) {
servers.remove(server);
}
}
}
package com.avaje.ebeaninternal.server.lib;
import com.avaje.ebean.common.SpiContainer;
import com.avaje.ebeaninternal.api.ClassUtil;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* Manages the shutdown of the JVM Runtime.
* <p>
* Makes sure all the resources are shutdown properly and in order.
* </p>
*/
public final class ShutdownManager {
private static final Logger logger = LoggerFactory.getLogger(ShutdownManager.class);
static final List<SpiEbeanServer> servers = new ArrayList<SpiEbeanServer>();
static final ShutdownHook shutdownHook = new ShutdownHook();
static boolean stopping;
static SpiContainer container;
static {
// Register the Shutdown hook
registerShutdownHook();
}
/**
* Disallow construction.
*/
private ShutdownManager() {
}
public static void registerContainer(SpiContainer ebeanContainer){
container = ebeanContainer;
}
/**
* Make sure the ShutdownManager is activated.
*/
public static void touch() {
// Do nothing
}
/**
* Return true if the system is in the process of stopping.
*/
public static boolean isStopping() {
synchronized (servers) {
return stopping;
}
}
/**
* Deregister the Shutdown hook.
* <p>
* For running in a Servlet Container a redeploy will cause a shutdown, and
* for that case we need to make sure the shutdown hook is deregistered.
* </p>
*/
protected static void deregisterShutdownHook() {
synchronized (servers) {
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
}
}
}
/**
* Register the shutdown hook with the Runtime.
*/
protected static void registerShutdownHook() {
synchronized (servers) {
try {
Runtime.getRuntime().addShutdownHook(shutdownHook);
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
}
}
}
/**
* Shutdown gracefully cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook.
* </p>
*/
public static void shutdown() {
synchronized (servers) {
if (stopping) {
// Already run shutdown...
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Shutting down");
}
stopping = true;
deregisterShutdownHook();
String shutdownRunner = System.getProperty("ebean.shutdown.runnable");
if (shutdownRunner != null) {
try {
// A custom runnable executed at the start of shutdown
Runnable r = (Runnable) ClassUtil.newInstance(shutdownRunner);
r.run();
} catch (Exception e) {
logger.error("Error running custom shutdown runnable", e);
}
}
if (container != null) {
// shutdown cluster networking if active
container.shutdown();
}
// shutdown any registered servers that have not
// already been shutdown manually
for (SpiEbeanServer server : servers) {
try {
server.shutdownManaged();
} catch (Exception ex) {
logger.error("Error executing shutdown runnable", ex);
ex.printStackTrace();
}
}
if ("true".equalsIgnoreCase(System.getProperty("ebean.datasource.deregisterAllDrivers", "false"))) {
deregisterAllJdbcDrivers();
}
}
}
private static void deregisterAllJdbcDrivers() {
// This manually deregisters all JDBC drivers
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
logger.info("Deregistering jdbc driver: "+driver);
DriverManager.deregisterDriver(driver);
} catch (SQLException e) {
logger.error("Error deregistering driver "+driver, e);
}
}
}
/**
* Register an ebeanServer to be shutdown when the JVM is shutdown.
*/
public static void registerEbeanServer(SpiEbeanServer server) {
synchronized (servers) {
servers.add(server);
}
}
/**
* Deregister an ebeanServer.
* <p>
* This is done when the ebeanServer is shutdown manually.
* </p>
*/
public static void unregisterEbeanServer(SpiEbeanServer server) {
synchronized (servers) {
servers.remove(server);
}
}
}
@@ -1,108 +1,108 @@
package com.avaje.ebeaninternal.server.lib.resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* Helper object used to find directories typically from the current working
* directory.
*/
public class DirectoryFinder {
private static final Logger logger = LoggerFactory.getLogger(DirectoryFinder.class);
/**
* Find a directory by search through subdirectories.
* <p>
* For example, used to find the WEB-INF directory starting from the current
* working directory.
* </p>
*
* <pre class="code">
*
* // search to a depth of 3 from the current working directory
* // looking for a directory WEB-INF that contains the subdirectory
* // data
*
* File dir = DirectoryFinder.find(null, &quot;WEB-INF/data&quot;, 3);
* if (dir != null) {
* //found the directory
* }
* </pre>
*/
public static File find(File startDir, String match, int maxDepth) {
String matchSub = null;
int slashPos = match.indexOf('/');
if (slashPos > -1) {
// match has sub directories
matchSub = match.substring(slashPos + 1);
match = match.substring(0, slashPos);
}
// search for the directory
File found = find(startDir, match, matchSub, 0, maxDepth);
if (found != null && matchSub != null) {
// match has sub directories
return new File(found, matchSub);
}
return found;
}
private static File find(File dir, String match, String matchSub, int depth, int maxDepth) {
if (dir == null) {
String curDir = System.getProperty("user.dir");
dir = new File(curDir);
}
if (dir.exists()) {
File[] list = dir.listFiles();
if (list != null){
for (int i = 0; i < list.length; i++) {
if (isMatch(list[i], match, matchSub)) {
return list[i];
}
}
// go through the directories again
// Aka *NOT* a depth first search
if (depth < maxDepth) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
File found = find(list[i], match, matchSub, depth + 1, maxDepth);
if (found != null) {
return found;
}
}
}
}
}
}
return null;
}
private static boolean isMatch(File f, String match, String matchSub) {
if (f == null) {
return false;
}
if (!f.isDirectory()) {
return false;
}
if (!f.getName().equalsIgnoreCase(match)) {
return false;
}
if (matchSub == null) {
return true;
}
File sub = new File(f, matchSub);
if (logger.isTraceEnabled()){
logger.trace("search; " + f.getPath());
}
return sub.exists();
}
}
package com.avaje.ebeaninternal.server.lib.resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* Helper object used to find directories typically from the current working
* directory.
*/
public class DirectoryFinder {
private static final Logger logger = LoggerFactory.getLogger(DirectoryFinder.class);
/**
* Find a directory by search through subdirectories.
* <p>
* For example, used to find the WEB-INF directory starting from the current
* working directory.
* </p>
*
* <pre class="code">
*
* // search to a depth of 3 from the current working directory
* // looking for a directory WEB-INF that contains the subdirectory
* // data
*
* File dir = DirectoryFinder.find(null, &quot;WEB-INF/data&quot;, 3);
* if (dir != null) {
* //found the directory
* }
* </pre>
*/
public static File find(File startDir, String match, int maxDepth) {
String matchSub = null;
int slashPos = match.indexOf('/');
if (slashPos > -1) {
// match has sub directories
matchSub = match.substring(slashPos + 1);
match = match.substring(0, slashPos);
}
// search for the directory
File found = find(startDir, match, matchSub, 0, maxDepth);
if (found != null && matchSub != null) {
// match has sub directories
return new File(found, matchSub);
}
return found;
}
private static File find(File dir, String match, String matchSub, int depth, int maxDepth) {
if (dir == null) {
String curDir = System.getProperty("user.dir");
dir = new File(curDir);
}
if (dir.exists()) {
File[] list = dir.listFiles();
if (list != null){
for (int i = 0; i < list.length; i++) {
if (isMatch(list[i], match, matchSub)) {
return list[i];
}
}
// go through the directories again
// Aka *NOT* a depth first search
if (depth < maxDepth) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
File found = find(list[i], match, matchSub, depth + 1, maxDepth);
if (found != null) {
return found;
}
}
}
}
}
}
return null;
}
private static boolean isMatch(File f, String match, String matchSub) {
if (f == null) {
return false;
}
if (!f.isDirectory()) {
return false;
}
if (!f.getName().equalsIgnoreCase(match)) {
return false;
}
if (matchSub == null) {
return true;
}
File sub = new File(f, matchSub);
if (logger.isTraceEnabled()){
logger.trace("search; " + f.getPath());
}
return sub.exists();
}
}
@@ -1,71 +1,71 @@
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
/**
* Content from a file system file.
*/
public class FileResourceContent implements ResourceContent {
/**
* The underlying file.
*/
File file;
String entryName;
/**
* Create with a File and the entryName.
*/
public FileResourceContent(File file, String entryName) {
this.file = file;
this.entryName = entryName;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[").append(getName());
sb.append("] size[").append(size());
sb.append("] lastModified[").append(new Date(lastModified()));
sb.append("]");
return sb.toString();
}
/**
* Returns the entry name which contains the path from the base directory.
* <p>
* This does not return the full path of the file, but the path relative to
* the FileIoSource directory.
* </p>
*/
public String getName() {
return entryName;
}
/**
* Return the time the file was last modified.
*/
public long lastModified() {
return file.lastModified();
}
/**
* Return the size of the file.
*/
public long size() {
return file.length();
}
/**
* Return the input stream for this file.
*/
public InputStream getInputStream() throws IOException {
FileInputStream is = new FileInputStream(file);
return is;
}
}
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
/**
* Content from a file system file.
*/
public class FileResourceContent implements ResourceContent {
/**
* The underlying file.
*/
File file;
String entryName;
/**
* Create with a File and the entryName.
*/
public FileResourceContent(File file, String entryName) {
this.file = file;
this.entryName = entryName;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[").append(getName());
sb.append("] size[").append(size());
sb.append("] lastModified[").append(new Date(lastModified()));
sb.append("]");
return sb.toString();
}
/**
* Returns the entry name which contains the path from the base directory.
* <p>
* This does not return the full path of the file, but the path relative to
* the FileIoSource directory.
* </p>
*/
public String getName() {
return entryName;
}
/**
* Return the time the file was last modified.
*/
public long lastModified() {
return file.lastModified();
}
/**
* Return the size of the file.
*/
public long size() {
return file.length();
}
/**
* Return the input stream for this file.
*/
public InputStream getInputStream() throws IOException {
FileInputStream is = new FileInputStream(file);
return is;
}
}
@@ -1,51 +1,51 @@
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.File;
/**
* A file system directory represented as a FileSource.
*/
public class FileResourceSource extends AbstractResourceSource implements ResourceSource {
/**
* The directory name.
*/
String directory;
String baseDir;
/**
* Create the source based on a directory name.
*/
public FileResourceSource(String directory){
this.directory = directory;
this.baseDir = directory+File.separator;
}
/**
* Create the source based on a directory file.
*/
public FileResourceSource(File dir){
this(dir.getPath());
}
public String getRealPath() {
return directory;
}
/**
* Search for the given file and return as IoContent.
*/
public ResourceContent getContent(String entry) {
String fullPath = baseDir+entry;
File f = new File(fullPath);
if (f.exists()){
FileResourceContent content = new FileResourceContent(f, entry);
return content;
}
return null;
}
}
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.File;
/**
* A file system directory represented as a FileSource.
*/
public class FileResourceSource extends AbstractResourceSource implements ResourceSource {
/**
* The directory name.
*/
String directory;
String baseDir;
/**
* Create the source based on a directory name.
*/
public FileResourceSource(String directory){
this.directory = directory;
this.baseDir = directory+File.separator;
}
/**
* Create the source based on a directory file.
*/
public FileResourceSource(File dir){
this(dir.getPath());
}
public String getRealPath() {
return directory;
}
/**
* Search for the given file and return as IoContent.
*/
public ResourceContent getContent(String entry) {
String fullPath = baseDir+entry;
File f = new File(fullPath);
if (f.exists()){
FileResourceContent content = new FileResourceContent(f, entry);
return content;
}
return null;
}
}
@@ -1,34 +1,34 @@
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.IOException;
import java.io.InputStream;
/**
* Represents content that can be read via the ResourceManager.
* <p>
* Typically either content from a File or a URL.
* </p>
*/
public interface ResourceContent {
/**
* The name of the content.
*/
public String getName();
/**
* The size of the content in bytes.
*/
public long size();
/**
* The last modified timestamp of the content.
*/
public long lastModified();
/**
* The content itself.
*/
public InputStream getInputStream() throws IOException;
}
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.IOException;
import java.io.InputStream;
/**
* Represents content that can be read via the ResourceManager.
* <p>
* Typically either content from a File or a URL.
* </p>
*/
public interface ResourceContent {
/**
* The name of the content.
*/
public String getName();
/**
* The size of the content in bytes.
*/
public long size();
/**
* The last modified timestamp of the content.
*/
public long lastModified();
/**
* The content itself.
*/
public InputStream getInputStream() throws IOException;
}
@@ -1,37 +1,37 @@
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.IOException;
/**
* A Source for ResourceManager.
* <p>
* Typically a File System Directory based source or a ServletContext URL
* resource based source (for Servlet WAR files).
* </p>
*/
public interface ResourceSource {
/**
* Return the File System path of the root of the ResourceSource.
* <p>
* This will return null IF the ResourceSource is an unpacked WAR file.
* </p>
*/
public String getRealPath();
/**
* Find the content with a given entry name. This will return null if no
* matching content was found.
*/
public ResourceContent getContent(String entry);
/**
* Return the content as a String.
*/
public String readString(ResourceContent content, int bufSize) throws IOException;
/**
* Return the content as a byte[].
*/
public byte[] readBytes(ResourceContent content, int bufSize) throws IOException;
}
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.IOException;
/**
* A Source for ResourceManager.
* <p>
* Typically a File System Directory based source or a ServletContext URL
* resource based source (for Servlet WAR files).
* </p>
*/
public interface ResourceSource {
/**
* Return the File System path of the root of the ResourceSource.
* <p>
* This will return null IF the ResourceSource is an unpacked WAR file.
* </p>
*/
public String getRealPath();
/**
* Find the content with a given entry name. This will return null if no
* matching content was found.
*/
public ResourceContent getContent(String entry);
/**
* Return the content as a String.
*/
public String readString(ResourceContent content, int bufSize) throws IOException;
/**
* Return the content as a byte[].
*/
public byte[] readBytes(ResourceContent content, int bufSize) throws IOException;
}
@@ -1,77 +1,77 @@
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
/**
* Content from a URL Resource.
*/
public class UrlResourceContent implements ResourceContent {
/**
* The underlying resource.
*/
//URL url;
String entryName;
URLConnection con;
/**
* Create with a File and the entryName.
*/
public UrlResourceContent(URL url, String entryName) {
//this.url = url;
this.entryName = entryName;
try {
con = url.openConnection();
} catch (IOException ex){
throw new RuntimeException(ex);
}
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[").append(getName());
sb.append("] size[").append(size());
sb.append("] lastModified[").append(new Date(lastModified()));
sb.append("]");
return sb.toString();
}
/**
* Returns the entry name which contains the path from the base directory.
* <p>
* This does not return the full path of the file, but the path relative to
* the FileIoSource directory.
* </p>
*/
public String getName() {
return entryName;
}
/**
* Return the time the file was last modified.
*/
public long lastModified() {
return con.getLastModified();
}
/**
* Return the size of the file.
*/
public long size() {
return con.getContentLength();
}
/**
* Return the input stream for this file.
*/
public InputStream getInputStream() throws IOException {
return con.getInputStream();
}
}
package com.avaje.ebeaninternal.server.lib.resource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
/**
* Content from a URL Resource.
*/
public class UrlResourceContent implements ResourceContent {
/**
* The underlying resource.
*/
//URL url;
String entryName;
URLConnection con;
/**
* Create with a File and the entryName.
*/
public UrlResourceContent(URL url, String entryName) {
//this.url = url;
this.entryName = entryName;
try {
con = url.openConnection();
} catch (IOException ex){
throw new RuntimeException(ex);
}
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[").append(getName());
sb.append("] size[").append(size());
sb.append("] lastModified[").append(new Date(lastModified()));
sb.append("]");
return sb.toString();
}
/**
* Returns the entry name which contains the path from the base directory.
* <p>
* This does not return the full path of the file, but the path relative to
* the FileIoSource directory.
* </p>
*/
public String getName() {
return entryName;
}
/**
* Return the time the file was last modified.
*/
public long lastModified() {
return con.getLastModified();
}
/**
* Return the size of the file.
*/
public long size() {
return con.getContentLength();
}
/**
* Return the input stream for this file.
*/
public InputStream getInputStream() throws IOException {
return con.getInputStream();
}
}
@@ -1,64 +1,64 @@
package com.avaje.ebeaninternal.server.lib.resource;
import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.ServletContext;
import com.avaje.ebeaninternal.server.lib.util.GeneralException;
/**
* A file system directory represented as a FileSource.
*/
public class UrlResourceSource extends AbstractResourceSource implements ResourceSource {
ServletContext sc;
String basePath;
String realPath;
/**
* Create the source based on a directory name.
*/
public UrlResourceSource(ServletContext sc, String basePath){
this.sc = sc;
if (basePath == null){
this.basePath = "/";
} else {
this.basePath = "/"+basePath+"/";
}
this.realPath = sc.getRealPath(basePath);
}
/**
* Returns the "real path" from the ServletContext root.
* <p>
* This can be null for unpacked WAR deployment.
* </p>
*/
public String getRealPath() {
return realPath;
}
/**
* Search for the given URL resource and return as ResourceContent.
* <p>
* Returns null if the resource is not found.
* </p>
*/
public ResourceContent getContent(String entry) {
try {
URL url = sc.getResource(basePath+entry);
if (url != null){
return new UrlResourceContent(url, entry);
}
return null;
} catch (MalformedURLException ex){
throw new GeneralException(ex);
}
}
}
package com.avaje.ebeaninternal.server.lib.resource;
import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.ServletContext;
import com.avaje.ebeaninternal.server.lib.util.GeneralException;
/**
* A file system directory represented as a FileSource.
*/
public class UrlResourceSource extends AbstractResourceSource implements ResourceSource {
ServletContext sc;
String basePath;
String realPath;
/**
* Create the source based on a directory name.
*/
public UrlResourceSource(ServletContext sc, String basePath){
this.sc = sc;
if (basePath == null){
this.basePath = "/";
} else {
this.basePath = "/"+basePath+"/";
}
this.realPath = sc.getRealPath(basePath);
}
/**
* Returns the "real path" from the ServletContext root.
* <p>
* This can be null for unpacked WAR deployment.
* </p>
*/
public String getRealPath() {
return realPath;
}
/**
* Search for the given URL resource and return as ResourceContent.
* <p>
* Returns null if the resource is not found.
* </p>
*/
public ResourceContent getContent(String entry) {
try {
URL url = sc.getResource(basePath+entry);
if (url != null){
return new UrlResourceContent(url, entry);
}
return null;
} catch (MalformedURLException ex){
throw new GeneralException(ex);
}
}
}
@@ -1,202 +1,202 @@
package com.avaje.ebeaninternal.server.lib.sql;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebeaninternal.server.lib.sql.PooledConnectionStatistics.LoadValues;
/**
* A buffer especially designed for Busy PooledConnections.
* <p>
* All thread safety controlled externally (by PooledConnectionQueue).
* </p>
* <p>
* It has a set of 'slots' and PooledConnections know which slot they went into
* and this allows for fast addition and removal (by slotId without looping).
* The capacity will increase on demand by the 'growBy' amount.
* </p>
*
* @author rbygrave
*
*/
class BusyConnectionBuffer {
private static final Logger logger = LoggerFactory.getLogger(BusyConnectionBuffer.class);
private PooledConnection[] slots;
private int growBy;
private int size;
private int pos = -1;
/**
* Create the buffer with an initial capacity and fixed growBy.
* We generally do not want the buffer to grow very often.
*
* @param capacity
* the initial capacity
* @param growBy
* the fixed amount to grow the buffer by.
*/
protected BusyConnectionBuffer(int capacity, int growBy) {
this.slots = new PooledConnection[capacity];
this.growBy = growBy;
}
/**
* We can only grow (not shrink) the capacity.
*/
protected void setCapacity(int newCapacity) {
if (newCapacity > slots.length){
PooledConnection[] current = this.slots;
this.slots = new PooledConnection[newCapacity];
System.arraycopy(current, 0, this.slots, 0, current.length);
}
}
public String toString() {
return Arrays.toString(slots);
}
protected int getCapacity() {
return slots.length;
}
protected int size(){
return size;
}
protected boolean isEmpty() {
return size == 0;
}
protected int add(PooledConnection pc){
if (size == slots.length){
// grow the capacity
setCapacity(slots.length + growBy);
}
int slot = nextEmptySlot();
pc.setSlotId(slot);
slots[slot] = pc;
return ++size;
}
protected boolean remove(PooledConnection pc) {
int slotId = pc.getSlotId();
if (slots[slotId] != pc){
PooledConnection heldBy = slots[slotId];
logger.warn("Failed to remove from slot[{}] PooledConnection[{}] - HeldBy[{}]", pc.getSlotId(), pc, heldBy);
return false;
}
slots[slotId] = null;
--size;
return true;
}
/**
* Collect the load statistics from all the busy connections.
* @param reset
*/
protected void collectStatistics(LoadValues values, boolean reset) {
for (int i = 0; i < slots.length; i++) {
if (slots[i] != null){
values.plus(slots[i].getStatistics().getValues(reset));
}
}
}
/**
* Close connections that should be considered leaked.
*/
protected void closeBusyConnections(long leakTimeMinutes) {
long olderThanTime = System.currentTimeMillis() - (leakTimeMinutes*60000);
logger.debug("Closing busy connections using leakTimeMinutes {}", leakTimeMinutes);
for (int i = 0; i < slots.length; i++) {
if (slots[i] != null){
//tmp.add(slots[i]);
PooledConnection pc = slots[i];
if (pc.isLongRunning() || pc.getLastUsedTime() > olderThanTime) {
// PooledConnection has been used recently or
// expected to be longRunning so not closing...
} else {
slots[i] = null;
--size;
closeBusyConnection(pc);
}
}
}
}
private void closeBusyConnection(PooledConnection pc) {
try {
logger.warn("DataSourcePool closing busy connection? "+pc.getFullDescription());
System.out.println("CLOSING busy connection: "+pc.getFullDescription());
pc.closeConnectionFully(false);
} catch (Exception ex) {
// this should never actually happen
logger.error("Error when closing potentially leaked connection "+pc.getDescription(), ex);
}
}
/**
* Returns information describing connections that are currently being used.
*/
protected String getBusyConnectionInformation(boolean toLogger) {
if (toLogger) {
logger.info("Dumping [{}] busy connections: (Use datasource.xxx.capturestacktrace=true ... to get stackTraces)", size());
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < slots.length; i++) {
if (slots[i] != null){
PooledConnection pc = slots[i];
if (toLogger) {
logger.info("Busy Connection - {}", pc.getFullDescription());
} else {
sb.append(pc.getFullDescription()).append("\r\n");
}
}
}
return sb.toString();
}
/**
* Return the position of the next empty slot.
*/
private int nextEmptySlot() {
// search forward
while(++pos < slots.length) {
if (slots[pos] == null){
return pos;
}
}
// search from beginning
pos = -1;
while(++pos < slots.length) {
if (slots[pos] == null){
return pos;
}
}
// not expecting this
throw new RuntimeException("No Empty Slot Found?");
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebeaninternal.server.lib.sql.PooledConnectionStatistics.LoadValues;
/**
* A buffer especially designed for Busy PooledConnections.
* <p>
* All thread safety controlled externally (by PooledConnectionQueue).
* </p>
* <p>
* It has a set of 'slots' and PooledConnections know which slot they went into
* and this allows for fast addition and removal (by slotId without looping).
* The capacity will increase on demand by the 'growBy' amount.
* </p>
*
* @author rbygrave
*
*/
class BusyConnectionBuffer {
private static final Logger logger = LoggerFactory.getLogger(BusyConnectionBuffer.class);
private PooledConnection[] slots;
private int growBy;
private int size;
private int pos = -1;
/**
* Create the buffer with an initial capacity and fixed growBy.
* We generally do not want the buffer to grow very often.
*
* @param capacity
* the initial capacity
* @param growBy
* the fixed amount to grow the buffer by.
*/
protected BusyConnectionBuffer(int capacity, int growBy) {
this.slots = new PooledConnection[capacity];
this.growBy = growBy;
}
/**
* We can only grow (not shrink) the capacity.
*/
protected void setCapacity(int newCapacity) {
if (newCapacity > slots.length){
PooledConnection[] current = this.slots;
this.slots = new PooledConnection[newCapacity];
System.arraycopy(current, 0, this.slots, 0, current.length);
}
}
public String toString() {
return Arrays.toString(slots);
}
protected int getCapacity() {
return slots.length;
}
protected int size(){
return size;
}
protected boolean isEmpty() {
return size == 0;
}
protected int add(PooledConnection pc){
if (size == slots.length){
// grow the capacity
setCapacity(slots.length + growBy);
}
int slot = nextEmptySlot();
pc.setSlotId(slot);
slots[slot] = pc;
return ++size;
}
protected boolean remove(PooledConnection pc) {
int slotId = pc.getSlotId();
if (slots[slotId] != pc){
PooledConnection heldBy = slots[slotId];
logger.warn("Failed to remove from slot[{}] PooledConnection[{}] - HeldBy[{}]", pc.getSlotId(), pc, heldBy);
return false;
}
slots[slotId] = null;
--size;
return true;
}
/**
* Collect the load statistics from all the busy connections.
* @param reset
*/
protected void collectStatistics(LoadValues values, boolean reset) {
for (int i = 0; i < slots.length; i++) {
if (slots[i] != null){
values.plus(slots[i].getStatistics().getValues(reset));
}
}
}
/**
* Close connections that should be considered leaked.
*/
protected void closeBusyConnections(long leakTimeMinutes) {
long olderThanTime = System.currentTimeMillis() - (leakTimeMinutes*60000);
logger.debug("Closing busy connections using leakTimeMinutes {}", leakTimeMinutes);
for (int i = 0; i < slots.length; i++) {
if (slots[i] != null){
//tmp.add(slots[i]);
PooledConnection pc = slots[i];
if (pc.isLongRunning() || pc.getLastUsedTime() > olderThanTime) {
// PooledConnection has been used recently or
// expected to be longRunning so not closing...
} else {
slots[i] = null;
--size;
closeBusyConnection(pc);
}
}
}
}
private void closeBusyConnection(PooledConnection pc) {
try {
logger.warn("DataSourcePool closing busy connection? "+pc.getFullDescription());
System.out.println("CLOSING busy connection: "+pc.getFullDescription());
pc.closeConnectionFully(false);
} catch (Exception ex) {
// this should never actually happen
logger.error("Error when closing potentially leaked connection "+pc.getDescription(), ex);
}
}
/**
* Returns information describing connections that are currently being used.
*/
protected String getBusyConnectionInformation(boolean toLogger) {
if (toLogger) {
logger.info("Dumping [{}] busy connections: (Use datasource.xxx.capturestacktrace=true ... to get stackTraces)", size());
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < slots.length; i++) {
if (slots[i] != null){
PooledConnection pc = slots[i];
if (toLogger) {
logger.info("Busy Connection - {}", pc.getFullDescription());
} else {
sb.append(pc.getFullDescription()).append("\r\n");
}
}
}
return sb.toString();
}
/**
* Return the position of the next empty slot.
*/
private int nextEmptySlot() {
// search forward
while(++pos < slots.length) {
if (slots[pos] == null){
return pos;
}
}
// search from beginning
pos = -1;
while(++pos < slots.length) {
if (slots[pos] == null){
return pos;
}
}
// not expecting this
throw new RuntimeException("No Empty Slot Found?");
}
}
@@ -1,24 +1,24 @@
package com.avaje.ebeaninternal.server.lib.sql;
/**
* A general DataSource exception.
*/
public class DataSourceException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539844L;
public DataSourceException(Exception cause) {
super(cause);
}
public DataSourceException(String s, Exception cause) {
super(s, cause);
}
public DataSourceException(String s) {
super(s);
}
}
package com.avaje.ebeaninternal.server.lib.sql;
/**
* A general DataSource exception.
*/
public class DataSourceException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539844L;
public DataSourceException(Exception cause) {
super(cause);
}
public DataSourceException(String s, Exception cause) {
super(s, cause);
}
public DataSourceException(String s) {
super(s);
}
}
File diff suppressed because it is too large Load Diff
@@ -1,389 +1,389 @@
package com.avaje.ebeaninternal.server.lib.sql;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
/**
* Extended PreparedStatement that supports caching.
* <p>
* Designed so that it can be cached by the PooledConnection. It additionally
* notes any Exceptions that occur and this is used to ensure bad connections
* are removed from the connection pool.
* </p>
*/
public class ExtendedPreparedStatement extends ExtendedStatement implements PreparedStatement {
/**
* The SQL used to create the underlying PreparedStatement.
*/
private final String sql;
/**
* The key used to cache this in the connection.
*/
private final String cacheKey;
/**
* Create a wrapped PreparedStatement that can be cached.
*/
public ExtendedPreparedStatement(PooledConnection pooledConnection, PreparedStatement pstmt, String sql, String cacheKey) {
super(pooledConnection, pstmt);
this.sql = sql;
this.cacheKey = cacheKey;
}
public PreparedStatement getDelegate() {
return pstmt;
}
/**
* Return the key used to cache this on the Connection.
*/
public String getCacheKey() {
return cacheKey;
}
/**
* Return the SQL used to create this PreparedStatement.
*/
public String getSql() {
return sql;
}
/**
* Fully close the underlying PreparedStatement. After this we can no longer
* reuse the PreparedStatement.
*/
public void closeDestroy() throws SQLException {
pstmt.close();
}
/**
* Returns the PreparedStatement back into the cache. This doesn't fully
* close the underlying PreparedStatement.
*/
public void close() throws SQLException {
// return the connection back into the cache.
pooledConnection.returnPreparedStatement(this);
}
/**
* Add the last binding for batch execution.
*/
public void addBatch() throws SQLException {
try {
pstmt.addBatch();
} catch (SQLException e) {
// we got an error... need to check this
// connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Clear parameters.
*/
public void clearParameters() throws SQLException {
try {
pstmt.clearParameters();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* execute the statement.
*/
public boolean execute() throws SQLException {
try {
return pstmt.execute();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute teh query.
*/
public ResultSet executeQuery() throws SQLException {
try {
return pstmt.executeQuery();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the dml statement.
*/
public int executeUpdate() throws SQLException {
try {
return pstmt.executeUpdate();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Return the MetaData for the query.
*/
public ResultSetMetaData getMetaData() throws SQLException {
try {
return pstmt.getMetaData();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Standard PreparedStatement method execution.
*/
public ParameterMetaData getParameterMetaData() throws SQLException {
return pstmt.getParameterMetaData();
}
/**
* Standard PreparedStatement method execution.
*/
public void setArray(int i, Array x) throws SQLException {
pstmt.setArray(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
pstmt.setAsciiStream(parameterIndex, x, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
pstmt.setBigDecimal(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
pstmt.setBinaryStream(parameterIndex, x, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBlob(int i, Blob x) throws SQLException {
pstmt.setBlob(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
pstmt.setBoolean(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setByte(int parameterIndex, byte x) throws SQLException {
pstmt.setByte(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
pstmt.setBytes(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setCharacterStream(int parameterIndex, Reader reader, int length)
throws SQLException {
pstmt.setCharacterStream(parameterIndex, reader, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setClob(int i, Clob x) throws SQLException {
pstmt.setClob(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setDate(int parameterIndex, Date x) throws SQLException {
pstmt.setDate(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
pstmt.setDate(parameterIndex, x, cal);
}
/**
* Standard PreparedStatement method execution.
*/
public void setDouble(int parameterIndex, double x) throws SQLException {
pstmt.setDouble(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setFloat(int parameterIndex, float x) throws SQLException {
pstmt.setFloat(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setInt(int parameterIndex, int x) throws SQLException {
pstmt.setInt(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setLong(int parameterIndex, long x) throws SQLException {
pstmt.setLong(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setNull(int parameterIndex, int sqlType) throws SQLException {
pstmt.setNull(parameterIndex, sqlType);
}
/**
* Standard PreparedStatement method execution.
*/
public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
pstmt.setNull(paramIndex, sqlType, typeName);
}
/**
* Standard PreparedStatement method execution.
*/
public void setObject(int parameterIndex, Object x) throws SQLException {
pstmt.setObject(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
pstmt.setObject(parameterIndex, x, targetSqlType);
}
/**
* Standard PreparedStatement method execution.
*/
public void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
throws SQLException {
pstmt.setObject(parameterIndex, x, targetSqlType, scale);
}
/**
* Standard PreparedStatement method execution.
*/
public void setRef(int i, Ref x) throws SQLException {
pstmt.setRef(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setShort(int parameterIndex, short x) throws SQLException {
pstmt.setShort(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setString(int parameterIndex, String x) throws SQLException {
pstmt.setString(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTime(int parameterIndex, Time x) throws SQLException {
pstmt.setTime(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
pstmt.setTime(parameterIndex, x, cal);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
pstmt.setTimestamp(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
pstmt.setTimestamp(parameterIndex, x, cal);
}
/**
* Standard PreparedStatement method execution.
* @deprecated
*/
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
pstmt.setUnicodeStream(parameterIndex, x, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setURL(int parameterIndex, URL x) throws SQLException {
pstmt.setURL(parameterIndex, x);
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
/**
* Extended PreparedStatement that supports caching.
* <p>
* Designed so that it can be cached by the PooledConnection. It additionally
* notes any Exceptions that occur and this is used to ensure bad connections
* are removed from the connection pool.
* </p>
*/
public class ExtendedPreparedStatement extends ExtendedStatement implements PreparedStatement {
/**
* The SQL used to create the underlying PreparedStatement.
*/
private final String sql;
/**
* The key used to cache this in the connection.
*/
private final String cacheKey;
/**
* Create a wrapped PreparedStatement that can be cached.
*/
public ExtendedPreparedStatement(PooledConnection pooledConnection, PreparedStatement pstmt, String sql, String cacheKey) {
super(pooledConnection, pstmt);
this.sql = sql;
this.cacheKey = cacheKey;
}
public PreparedStatement getDelegate() {
return pstmt;
}
/**
* Return the key used to cache this on the Connection.
*/
public String getCacheKey() {
return cacheKey;
}
/**
* Return the SQL used to create this PreparedStatement.
*/
public String getSql() {
return sql;
}
/**
* Fully close the underlying PreparedStatement. After this we can no longer
* reuse the PreparedStatement.
*/
public void closeDestroy() throws SQLException {
pstmt.close();
}
/**
* Returns the PreparedStatement back into the cache. This doesn't fully
* close the underlying PreparedStatement.
*/
public void close() throws SQLException {
// return the connection back into the cache.
pooledConnection.returnPreparedStatement(this);
}
/**
* Add the last binding for batch execution.
*/
public void addBatch() throws SQLException {
try {
pstmt.addBatch();
} catch (SQLException e) {
// we got an error... need to check this
// connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Clear parameters.
*/
public void clearParameters() throws SQLException {
try {
pstmt.clearParameters();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* execute the statement.
*/
public boolean execute() throws SQLException {
try {
return pstmt.execute();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute teh query.
*/
public ResultSet executeQuery() throws SQLException {
try {
return pstmt.executeQuery();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the dml statement.
*/
public int executeUpdate() throws SQLException {
try {
return pstmt.executeUpdate();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Return the MetaData for the query.
*/
public ResultSetMetaData getMetaData() throws SQLException {
try {
return pstmt.getMetaData();
} catch (SQLException e) {
// we got an error... need to check
// this connection before returning it
pooledConnection.addError(e);
throw e;
}
}
/**
* Standard PreparedStatement method execution.
*/
public ParameterMetaData getParameterMetaData() throws SQLException {
return pstmt.getParameterMetaData();
}
/**
* Standard PreparedStatement method execution.
*/
public void setArray(int i, Array x) throws SQLException {
pstmt.setArray(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
pstmt.setAsciiStream(parameterIndex, x, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
pstmt.setBigDecimal(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
pstmt.setBinaryStream(parameterIndex, x, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBlob(int i, Blob x) throws SQLException {
pstmt.setBlob(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
pstmt.setBoolean(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setByte(int parameterIndex, byte x) throws SQLException {
pstmt.setByte(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
pstmt.setBytes(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setCharacterStream(int parameterIndex, Reader reader, int length)
throws SQLException {
pstmt.setCharacterStream(parameterIndex, reader, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setClob(int i, Clob x) throws SQLException {
pstmt.setClob(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setDate(int parameterIndex, Date x) throws SQLException {
pstmt.setDate(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
pstmt.setDate(parameterIndex, x, cal);
}
/**
* Standard PreparedStatement method execution.
*/
public void setDouble(int parameterIndex, double x) throws SQLException {
pstmt.setDouble(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setFloat(int parameterIndex, float x) throws SQLException {
pstmt.setFloat(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setInt(int parameterIndex, int x) throws SQLException {
pstmt.setInt(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setLong(int parameterIndex, long x) throws SQLException {
pstmt.setLong(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setNull(int parameterIndex, int sqlType) throws SQLException {
pstmt.setNull(parameterIndex, sqlType);
}
/**
* Standard PreparedStatement method execution.
*/
public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
pstmt.setNull(paramIndex, sqlType, typeName);
}
/**
* Standard PreparedStatement method execution.
*/
public void setObject(int parameterIndex, Object x) throws SQLException {
pstmt.setObject(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
pstmt.setObject(parameterIndex, x, targetSqlType);
}
/**
* Standard PreparedStatement method execution.
*/
public void setObject(int parameterIndex, Object x, int targetSqlType, int scale)
throws SQLException {
pstmt.setObject(parameterIndex, x, targetSqlType, scale);
}
/**
* Standard PreparedStatement method execution.
*/
public void setRef(int i, Ref x) throws SQLException {
pstmt.setRef(i, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setShort(int parameterIndex, short x) throws SQLException {
pstmt.setShort(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setString(int parameterIndex, String x) throws SQLException {
pstmt.setString(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTime(int parameterIndex, Time x) throws SQLException {
pstmt.setTime(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
pstmt.setTime(parameterIndex, x, cal);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
pstmt.setTimestamp(parameterIndex, x);
}
/**
* Standard PreparedStatement method execution.
*/
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
pstmt.setTimestamp(parameterIndex, x, cal);
}
/**
* Standard PreparedStatement method execution.
* @deprecated
*/
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
pstmt.setUnicodeStream(parameterIndex, x, length);
}
/**
* Standard PreparedStatement method execution.
*/
public void setURL(int parameterIndex, URL x) throws SQLException {
pstmt.setURL(parameterIndex, x);
}
}
@@ -1,328 +1,328 @@
package com.avaje.ebeaninternal.server.lib.sql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import com.avaje.ebeaninternal.jdbc.PreparedStatementDelegator;
/**
* Implements the Statement methods for ExtendedPreparedStatement.
* <p>
* PreparedStatements should always be used and the intention is that there
* should be no use of Statement at all. The implementation here is generally
* for the case where someone uses the Statement api on an ExtendedPreparedStatement.
* </p>
*/
public abstract class ExtendedStatement extends PreparedStatementDelegator
{
/**
* The pooled connection this Statement belongs to.
*/
protected final PooledConnection pooledConnection;
/**
* The underlying Statement that this object wraps.
*/
protected final PreparedStatement pstmt;
/**
* Create the ExtendedStatement for a given pooledConnection.
*/
public ExtendedStatement(PooledConnection pooledConnection, PreparedStatement pstmt) {
super(pstmt);
this.pooledConnection = pooledConnection;
this.pstmt = pstmt;
}
/**
* Put the statement back into the statement cache.
*/
public abstract void close() throws SQLException;
/**
* Return the underlying connection.
*/
public Connection getConnection() throws SQLException {
try {
return pstmt.getConnection();
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Add the sql for batch execution.
*/
public void addBatch(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
pstmt.addBatch(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the sql.
*/
public boolean execute(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
return pstmt.execute(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the query.
*/
public ResultSet executeQuery(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
return pstmt.executeQuery(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the dml sql.
*/
public int executeUpdate(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
return pstmt.executeUpdate(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Standard Statement method call.
*/
public int[] executeBatch() throws SQLException {
return pstmt.executeBatch();
}
/**
* Standard Statement method call.
*/
public void cancel() throws SQLException {
pstmt.cancel();
}
/**
* Standard Statement method call.
*/
public void clearBatch() throws SQLException {
pstmt.clearBatch();
}
/**
* Standard Statement method call.
*/
public void clearWarnings() throws SQLException {
pstmt.clearWarnings();
}
/**
* Standard Statement method call.
*/
public int getFetchDirection() throws SQLException {
return pstmt.getFetchDirection();
}
/**
* Standard Statement method call.
*/
public int getFetchSize() throws SQLException {
return pstmt.getFetchSize();
}
/**
* Standard Statement method call.
*/
public int getMaxFieldSize() throws SQLException {
return pstmt.getMaxFieldSize();
}
/**
* Standard Statement method call.
*/
public int getMaxRows() throws SQLException {
return pstmt.getMaxRows();
}
/**
* Standard Statement method call.
*/
public boolean getMoreResults() throws SQLException {
return pstmt.getMoreResults();
}
/**
* Standard Statement method call.
*/
public int getQueryTimeout() throws SQLException {
return pstmt.getQueryTimeout();
}
/**
* Standard Statement method call.
*/
public ResultSet getResultSet() throws SQLException {
return pstmt.getResultSet();
}
/**
* Standard Statement method call.
*/
public int getResultSetConcurrency() throws SQLException {
return pstmt.getResultSetConcurrency();
}
/**
* Standard Statement method call.
*/
public int getResultSetType() throws SQLException {
return pstmt.getResultSetType();
}
/**
* Standard Statement method call.
*/
public int getUpdateCount() throws SQLException {
return pstmt.getUpdateCount();
}
/**
* Standard Statement method call.
*/
public SQLWarning getWarnings() throws SQLException {
return pstmt.getWarnings();
}
/**
* Standard Statement method call.
*/
public void setCursorName(String name) throws SQLException {
pstmt.setCursorName(name);
}
/**
* Standard Statement method call.
*/
public void setEscapeProcessing(boolean enable) throws SQLException {
pstmt.setEscapeProcessing(enable);
}
/**
* Standard Statement method call.
*/
public void setFetchDirection(int direction) throws SQLException {
pstmt.setFetchDirection(direction);
}
/**
* Standard Statement method call.
*/
public void setFetchSize(int rows) throws SQLException {
pstmt.setFetchSize(rows);
}
/**
* Standard Statement method call.
*/
public void setMaxFieldSize(int max) throws SQLException {
pstmt.setMaxFieldSize(max);
}
/**
* Standard Statement method call.
*/
public void setMaxRows(int max) throws SQLException {
pstmt.setMaxRows(max);
}
/**
* Standard Statement method call.
*/
public void setQueryTimeout(int seconds) throws SQLException {
pstmt.setQueryTimeout(seconds);
}
/**
* Standard Statement method call.
*/
public boolean getMoreResults(int i) throws SQLException {
return pstmt.getMoreResults(i);
}
/**
* Standard Statement method call.
*/
public ResultSet getGeneratedKeys() throws SQLException {
return pstmt.getGeneratedKeys();
}
/**
* Standard Statement method call.
*/
public int executeUpdate(String s, int i) throws SQLException {
return pstmt.executeUpdate(s, i);
}
/**
* Standard Statement method call.
*/
public int executeUpdate(String s, int[] i) throws SQLException {
return pstmt.executeUpdate(s, i);
}
/**
* Standard Statement method call.
*/
public int executeUpdate(String s, String[] i) throws SQLException {
return pstmt.executeUpdate(s, i);
}
/**
* Standard Statement method call.
*/
public boolean execute(String s, int i) throws SQLException {
return pstmt.execute(s, i);
}
/**
* Standard Statement method call.
*/
public boolean execute(String s, int[] i) throws SQLException {
return pstmt.execute(s, i);
}
/**
* Standard Statement method call.
*/
public boolean execute(String s, String[] i) throws SQLException {
return pstmt.execute(s, i);
}
/**
* Standard Statement method call.
*/
public int getResultSetHoldability() throws SQLException {
return pstmt.getResultSetHoldability();
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import com.avaje.ebeaninternal.jdbc.PreparedStatementDelegator;
/**
* Implements the Statement methods for ExtendedPreparedStatement.
* <p>
* PreparedStatements should always be used and the intention is that there
* should be no use of Statement at all. The implementation here is generally
* for the case where someone uses the Statement api on an ExtendedPreparedStatement.
* </p>
*/
public abstract class ExtendedStatement extends PreparedStatementDelegator
{
/**
* The pooled connection this Statement belongs to.
*/
protected final PooledConnection pooledConnection;
/**
* The underlying Statement that this object wraps.
*/
protected final PreparedStatement pstmt;
/**
* Create the ExtendedStatement for a given pooledConnection.
*/
public ExtendedStatement(PooledConnection pooledConnection, PreparedStatement pstmt) {
super(pstmt);
this.pooledConnection = pooledConnection;
this.pstmt = pstmt;
}
/**
* Put the statement back into the statement cache.
*/
public abstract void close() throws SQLException;
/**
* Return the underlying connection.
*/
public Connection getConnection() throws SQLException {
try {
return pstmt.getConnection();
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Add the sql for batch execution.
*/
public void addBatch(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
pstmt.addBatch(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the sql.
*/
public boolean execute(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
return pstmt.execute(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the query.
*/
public ResultSet executeQuery(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
return pstmt.executeQuery(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Execute the dml sql.
*/
public int executeUpdate(String sql) throws SQLException {
try {
pooledConnection.setLastStatement(sql);
return pstmt.executeUpdate(sql);
} catch (SQLException e) {
pooledConnection.addError(e);
throw e;
}
}
/**
* Standard Statement method call.
*/
public int[] executeBatch() throws SQLException {
return pstmt.executeBatch();
}
/**
* Standard Statement method call.
*/
public void cancel() throws SQLException {
pstmt.cancel();
}
/**
* Standard Statement method call.
*/
public void clearBatch() throws SQLException {
pstmt.clearBatch();
}
/**
* Standard Statement method call.
*/
public void clearWarnings() throws SQLException {
pstmt.clearWarnings();
}
/**
* Standard Statement method call.
*/
public int getFetchDirection() throws SQLException {
return pstmt.getFetchDirection();
}
/**
* Standard Statement method call.
*/
public int getFetchSize() throws SQLException {
return pstmt.getFetchSize();
}
/**
* Standard Statement method call.
*/
public int getMaxFieldSize() throws SQLException {
return pstmt.getMaxFieldSize();
}
/**
* Standard Statement method call.
*/
public int getMaxRows() throws SQLException {
return pstmt.getMaxRows();
}
/**
* Standard Statement method call.
*/
public boolean getMoreResults() throws SQLException {
return pstmt.getMoreResults();
}
/**
* Standard Statement method call.
*/
public int getQueryTimeout() throws SQLException {
return pstmt.getQueryTimeout();
}
/**
* Standard Statement method call.
*/
public ResultSet getResultSet() throws SQLException {
return pstmt.getResultSet();
}
/**
* Standard Statement method call.
*/
public int getResultSetConcurrency() throws SQLException {
return pstmt.getResultSetConcurrency();
}
/**
* Standard Statement method call.
*/
public int getResultSetType() throws SQLException {
return pstmt.getResultSetType();
}
/**
* Standard Statement method call.
*/
public int getUpdateCount() throws SQLException {
return pstmt.getUpdateCount();
}
/**
* Standard Statement method call.
*/
public SQLWarning getWarnings() throws SQLException {
return pstmt.getWarnings();
}
/**
* Standard Statement method call.
*/
public void setCursorName(String name) throws SQLException {
pstmt.setCursorName(name);
}
/**
* Standard Statement method call.
*/
public void setEscapeProcessing(boolean enable) throws SQLException {
pstmt.setEscapeProcessing(enable);
}
/**
* Standard Statement method call.
*/
public void setFetchDirection(int direction) throws SQLException {
pstmt.setFetchDirection(direction);
}
/**
* Standard Statement method call.
*/
public void setFetchSize(int rows) throws SQLException {
pstmt.setFetchSize(rows);
}
/**
* Standard Statement method call.
*/
public void setMaxFieldSize(int max) throws SQLException {
pstmt.setMaxFieldSize(max);
}
/**
* Standard Statement method call.
*/
public void setMaxRows(int max) throws SQLException {
pstmt.setMaxRows(max);
}
/**
* Standard Statement method call.
*/
public void setQueryTimeout(int seconds) throws SQLException {
pstmt.setQueryTimeout(seconds);
}
/**
* Standard Statement method call.
*/
public boolean getMoreResults(int i) throws SQLException {
return pstmt.getMoreResults(i);
}
/**
* Standard Statement method call.
*/
public ResultSet getGeneratedKeys() throws SQLException {
return pstmt.getGeneratedKeys();
}
/**
* Standard Statement method call.
*/
public int executeUpdate(String s, int i) throws SQLException {
return pstmt.executeUpdate(s, i);
}
/**
* Standard Statement method call.
*/
public int executeUpdate(String s, int[] i) throws SQLException {
return pstmt.executeUpdate(s, i);
}
/**
* Standard Statement method call.
*/
public int executeUpdate(String s, String[] i) throws SQLException {
return pstmt.executeUpdate(s, i);
}
/**
* Standard Statement method call.
*/
public boolean execute(String s, int i) throws SQLException {
return pstmt.execute(s, i);
}
/**
* Standard Statement method call.
*/
public boolean execute(String s, int[] i) throws SQLException {
return pstmt.execute(s, i);
}
/**
* Standard Statement method call.
*/
public boolean execute(String s, String[] i) throws SQLException {
return pstmt.execute(s, i);
}
/**
* Standard Statement method call.
*/
public int getResultSetHoldability() throws SQLException {
return pstmt.getResultSetHoldability();
}
}
@@ -1,106 +1,106 @@
package com.avaje.ebeaninternal.server.lib.sql;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebeaninternal.server.lib.sql.PooledConnectionStatistics.LoadValues;
/**
* A buffer designed especially to hold free pooled connections.
* <p>
* All thread safety controlled externally (by PooledConnectionQueue).
* </p>
*/
class FreeConnectionBuffer {
private static final Logger logger = LoggerFactory.getLogger(FreeConnectionBuffer.class);
/**
* Buffer oriented for add and remove.
*/
private final LinkedList<PooledConnection> freeBuffer = new LinkedList<PooledConnection>();
protected FreeConnectionBuffer() {
}
protected int size() {
return freeBuffer.size();
}
protected boolean isEmpty() {
return freeBuffer.isEmpty();
}
/**
* Add connection to the free list.
*/
protected void add(PooledConnection pc) {
freeBuffer.addLast(pc);
}
/**
* Remove a connection from the free list.
*/
protected PooledConnection remove() {
return freeBuffer.removeFirst();
}
/**
* Close all connections in this buffer.
*/
protected void closeAll(boolean logErrors) {
// create a temporary list
List<PooledConnection> tempList = new ArrayList<PooledConnection>(freeBuffer.size());
// add all the connections into it
for (PooledConnection c : freeBuffer) {
tempList.add(c);
}
// clear the buffer (in case it takes some time to close these connections).
freeBuffer.clear();
logger.debug("... closing all {} connections from the free list with logErrors: {}", tempList.size(), logErrors);
for (int i = 0; i < tempList.size(); i++) {
PooledConnection pooledConnection = tempList.get(i);
logger.debug("... closing {} of {} connections from the free list", i, tempList.size());
pooledConnection.closeConnectionFully(logErrors);
}
}
/**
* Trim any inactive connections that have not been used since usedSince.
*/
protected int trim(long usedSince, long createdSince) {
int trimCount = 0;
Iterator<PooledConnection> iterator = freeBuffer.iterator();
while (iterator.hasNext()) {
PooledConnection pooledConnection = iterator.next();
if (pooledConnection.shouldTrim(usedSince, createdSince)) {
iterator.remove();
pooledConnection.closeConnectionFully(true);
trimCount++;
}
}
return trimCount;
}
/**
* Collect the load statistics from all the free connections.
*/
protected void collectStatistics(LoadValues values, boolean reset) {
for (PooledConnection c : freeBuffer) {
values.plus(c.getStatistics().getValues(reset));
}
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebeaninternal.server.lib.sql.PooledConnectionStatistics.LoadValues;
/**
* A buffer designed especially to hold free pooled connections.
* <p>
* All thread safety controlled externally (by PooledConnectionQueue).
* </p>
*/
class FreeConnectionBuffer {
private static final Logger logger = LoggerFactory.getLogger(FreeConnectionBuffer.class);
/**
* Buffer oriented for add and remove.
*/
private final LinkedList<PooledConnection> freeBuffer = new LinkedList<PooledConnection>();
protected FreeConnectionBuffer() {
}
protected int size() {
return freeBuffer.size();
}
protected boolean isEmpty() {
return freeBuffer.isEmpty();
}
/**
* Add connection to the free list.
*/
protected void add(PooledConnection pc) {
freeBuffer.addLast(pc);
}
/**
* Remove a connection from the free list.
*/
protected PooledConnection remove() {
return freeBuffer.removeFirst();
}
/**
* Close all connections in this buffer.
*/
protected void closeAll(boolean logErrors) {
// create a temporary list
List<PooledConnection> tempList = new ArrayList<PooledConnection>(freeBuffer.size());
// add all the connections into it
for (PooledConnection c : freeBuffer) {
tempList.add(c);
}
// clear the buffer (in case it takes some time to close these connections).
freeBuffer.clear();
logger.debug("... closing all {} connections from the free list with logErrors: {}", tempList.size(), logErrors);
for (int i = 0; i < tempList.size(); i++) {
PooledConnection pooledConnection = tempList.get(i);
logger.debug("... closing {} of {} connections from the free list", i, tempList.size());
pooledConnection.closeConnectionFully(logErrors);
}
}
/**
* Trim any inactive connections that have not been used since usedSince.
*/
protected int trim(long usedSince, long createdSince) {
int trimCount = 0;
Iterator<PooledConnection> iterator = freeBuffer.iterator();
while (iterator.hasNext()) {
PooledConnection pooledConnection = iterator.next();
if (pooledConnection.shouldTrim(usedSince, createdSince)) {
iterator.remove();
pooledConnection.closeConnectionFully(true);
trimCount++;
}
}
return trimCount;
}
/**
* Collect the load statistics from all the free connections.
*/
protected void collectStatistics(LoadValues values, boolean reset) {
for (PooledConnection c : freeBuffer) {
values.plus(c.getStatistics().getValues(reset));
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,100 +1,100 @@
package com.avaje.ebeaninternal.server.lib.sql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Random;
/**
* Security mechanisim.
*/
public class Prefix {
private static final Logger logger = LoggerFactory.getLogger(Prefix.class);
private static final int[] oa = { 50, 12, 4, 6, 8, 10, 7, 23, 45, 23, 6, 9, 12, 2, 8, 34 };
public static String getProp(String prop) {
String v = dec(prop);
int p = v.indexOf(":");
String r = v.substring(1, p);
return r;
}
public static void main(String[] args) {
String m = e(args[0]);
logger.info("[" + m + "]");
String o = getProp(m);
logger.info("[" + o + "]");
}
public static String e(String msg) {
msg = elen(msg, 40);
return enc(msg);
}
public static byte az(byte c, int offset) {
int z = c + offset;
if (z > 122) {
// dp("z> "+z);
z = z - 122 + 48 - 1;
}
// dp("z="+z+" c:"+(int)c);
return (byte) z;
}
public static byte bz(byte c, int offset) {
int z = c - offset;
if (z < (48)) {
// dp("z< "+z);
z = z + 122 - 48 + 1;
}
return (byte) z;
}
public static String enc(String msg) {
byte[] msgbytes = msg.getBytes();
byte[] encbytes = new byte[msgbytes.length + 1];
Random r = new Random();
int key = r.nextInt(70);
char k = (char) (key + 48);
encbytes[0] = az((byte) k, oa[0]);
// dp("key:"+key+" encbytes[0]:"+(byte)encbytes[0]);
int ios = key;
for (int i = 1; i < (msgbytes.length + 1); i++) {
encbytes[i] = az(msgbytes[i - 1], (oa[(i + ios) % oa.length]));
}
return new String(encbytes);
}
public static String dec(String msg) {
byte[] msgbytes = msg.getBytes();
byte[] encbytes = new byte[msgbytes.length];
encbytes[0] = bz(msgbytes[0], oa[0]);
byte key = encbytes[0];
int ios = (key - 48);
for (int i = 1; i < msgbytes.length; i++) {
encbytes[i] = bz(msgbytes[i], oa[(i + ios) % oa.length]);
}
return new String(encbytes);
}
public static String elen(String msg, int len) {
Random r = new Random();
if (msg.length() < len) {
int max = len - msg.length();
StringBuilder sb = new StringBuilder();
sb.append(msg).append(":");
for (int i = 1; i < max; i++) {
int bc = r.nextInt(122 - 48);
sb.append(Character.toString((char) (bc + 48)));
}
return sb.toString();
}
return msg;
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Random;
/**
* Security mechanisim.
*/
public class Prefix {
private static final Logger logger = LoggerFactory.getLogger(Prefix.class);
private static final int[] oa = { 50, 12, 4, 6, 8, 10, 7, 23, 45, 23, 6, 9, 12, 2, 8, 34 };
public static String getProp(String prop) {
String v = dec(prop);
int p = v.indexOf(":");
String r = v.substring(1, p);
return r;
}
public static void main(String[] args) {
String m = e(args[0]);
logger.info("[" + m + "]");
String o = getProp(m);
logger.info("[" + o + "]");
}
public static String e(String msg) {
msg = elen(msg, 40);
return enc(msg);
}
public static byte az(byte c, int offset) {
int z = c + offset;
if (z > 122) {
// dp("z> "+z);
z = z - 122 + 48 - 1;
}
// dp("z="+z+" c:"+(int)c);
return (byte) z;
}
public static byte bz(byte c, int offset) {
int z = c - offset;
if (z < (48)) {
// dp("z< "+z);
z = z + 122 - 48 + 1;
}
return (byte) z;
}
public static String enc(String msg) {
byte[] msgbytes = msg.getBytes();
byte[] encbytes = new byte[msgbytes.length + 1];
Random r = new Random();
int key = r.nextInt(70);
char k = (char) (key + 48);
encbytes[0] = az((byte) k, oa[0]);
// dp("key:"+key+" encbytes[0]:"+(byte)encbytes[0]);
int ios = key;
for (int i = 1; i < (msgbytes.length + 1); i++) {
encbytes[i] = az(msgbytes[i - 1], (oa[(i + ios) % oa.length]));
}
return new String(encbytes);
}
public static String dec(String msg) {
byte[] msgbytes = msg.getBytes();
byte[] encbytes = new byte[msgbytes.length];
encbytes[0] = bz(msgbytes[0], oa[0]);
byte key = encbytes[0];
int ios = (key - 48);
for (int i = 1; i < msgbytes.length; i++) {
encbytes[i] = bz(msgbytes[i], oa[(i + ios) % oa.length]);
}
return new String(encbytes);
}
public static String elen(String msg, int len) {
Random r = new Random();
if (msg.length() < len) {
int max = len - msg.length();
StringBuilder sb = new StringBuilder();
sb.append(msg).append(":");
for (int i = 1; i < max; i++) {
int bc = r.nextInt(122 - 48);
sb.append(Character.toString((char) (bc + 48)));
}
return sb.toString();
}
return msg;
}
}
@@ -1,183 +1,183 @@
package com.avaje.ebeaninternal.server.lib.sql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* A LRU based cache for PreparedStatements.
*/
public class PstmtCache extends LinkedHashMap<String, ExtendedPreparedStatement> {
private static final Logger logger = LoggerFactory.getLogger(PstmtCache.class);
static final long serialVersionUID = -3096406924865550697L;
/**
* The name of the cache, for tracing purposes.
*/
protected final String cacheName;
/**
* The maximum size of the cache. When this is exceeded the oldest entry is removed.
*/
private final int maxSize;
/**
* The total number of entries removed from this cache.
*/
private int removeCounter;
/**
* The number of get hits.
*/
private int hitCounter;
/**
* The number of get() misses.
*/
private int missCounter;
/**
* The number of puts into this cache.
*/
private int putCounter;
public PstmtCache(String cacheName, int maxCacheSize) {
// note = access ordered list. This is what gives it the LRU order
super(maxCacheSize*3, 0.75f, true);
this.cacheName = cacheName;
this.maxSize = maxCacheSize;
}
/**
* Return a summary description of this cache.
*/
public String getDescription() {
return "size["+size()+"] max["+maxSize+"] hits["+hitCounter+"] miss["+missCounter+"] hitRatio["+getHitRatio()+"] removes["+removeCounter+"]";
}
/**
* returns the current maximum size of the cache.
*/
public int getMaxSize() {
return maxSize;
}
/**
* Gets the hit ratio. A number between 0 and 100 indicating the number of
* hits to misses. A number approaching 100 is desirable.
*/
public int getHitRatio() {
if (hitCounter == 0) {
return 0;
} else {
return hitCounter*100/(hitCounter+missCounter);
}
}
/**
* The total number of hits against this cache.
*/
public int getHitCounter() {
return hitCounter;
}
/**
* The total number of misses against this cache.
*/
public int getMissCounter() {
return missCounter;
}
/**
* The total number of puts against this cache.
*/
public int getPutCounter() {
return putCounter;
}
/**
* Try to add the returning statement to the cache. If there is already a
* matching ExtendedPreparedStatement in the cache return false else add
* the statement to the cache and return true.
*/
public boolean returnStatement(ExtendedPreparedStatement pstmt) {
ExtendedPreparedStatement alreadyInCache = super.get(pstmt.getCacheKey());
if (alreadyInCache != null) {
return false;
}
// add the returning prepared statement to the cache.
// Note that the LRUCache will automatically close fully old unused
// PStmts when the cache has hit its maximum size.
put(pstmt.getCacheKey(), pstmt);
return true;
}
/**
* additionally maintains hit and miss statistics.
*/
public ExtendedPreparedStatement get(Object key) {
ExtendedPreparedStatement o = super.get(key);
if (o == null) {
missCounter++;
} else {
hitCounter++;
}
return o;
}
/**
* additionally maintains hit and miss statistics.
*/
public ExtendedPreparedStatement remove(Object key) {
ExtendedPreparedStatement o = super.remove(key);
if (o == null) {
missCounter++;
} else {
hitCounter++;
}
return o;
}
/**
* additionally maintains put counter statistics.
*/
public ExtendedPreparedStatement put(String key, ExtendedPreparedStatement value) {
putCounter++;
return super.put(key, value);
}
/**
* will check to see if we need to remove entries and
* if so call the cacheCleanup.cleanupEldestLRUCacheEntry() if
* one has been set.
*/
protected boolean removeEldestEntry(Map.Entry<String,ExtendedPreparedStatement> eldest) {
if (size() < maxSize) {
return false;
}
removeCounter++;
try {
ExtendedPreparedStatement pstmt = eldest.getValue();
pstmt.closeDestroy();
} catch (SQLException e) {
logger.error("Error closing ExtendedPreparedStatement", e);
}
return true;
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* A LRU based cache for PreparedStatements.
*/
public class PstmtCache extends LinkedHashMap<String, ExtendedPreparedStatement> {
private static final Logger logger = LoggerFactory.getLogger(PstmtCache.class);
static final long serialVersionUID = -3096406924865550697L;
/**
* The name of the cache, for tracing purposes.
*/
protected final String cacheName;
/**
* The maximum size of the cache. When this is exceeded the oldest entry is removed.
*/
private final int maxSize;
/**
* The total number of entries removed from this cache.
*/
private int removeCounter;
/**
* The number of get hits.
*/
private int hitCounter;
/**
* The number of get() misses.
*/
private int missCounter;
/**
* The number of puts into this cache.
*/
private int putCounter;
public PstmtCache(String cacheName, int maxCacheSize) {
// note = access ordered list. This is what gives it the LRU order
super(maxCacheSize*3, 0.75f, true);
this.cacheName = cacheName;
this.maxSize = maxCacheSize;
}
/**
* Return a summary description of this cache.
*/
public String getDescription() {
return "size["+size()+"] max["+maxSize+"] hits["+hitCounter+"] miss["+missCounter+"] hitRatio["+getHitRatio()+"] removes["+removeCounter+"]";
}
/**
* returns the current maximum size of the cache.
*/
public int getMaxSize() {
return maxSize;
}
/**
* Gets the hit ratio. A number between 0 and 100 indicating the number of
* hits to misses. A number approaching 100 is desirable.
*/
public int getHitRatio() {
if (hitCounter == 0) {
return 0;
} else {
return hitCounter*100/(hitCounter+missCounter);
}
}
/**
* The total number of hits against this cache.
*/
public int getHitCounter() {
return hitCounter;
}
/**
* The total number of misses against this cache.
*/
public int getMissCounter() {
return missCounter;
}
/**
* The total number of puts against this cache.
*/
public int getPutCounter() {
return putCounter;
}
/**
* Try to add the returning statement to the cache. If there is already a
* matching ExtendedPreparedStatement in the cache return false else add
* the statement to the cache and return true.
*/
public boolean returnStatement(ExtendedPreparedStatement pstmt) {
ExtendedPreparedStatement alreadyInCache = super.get(pstmt.getCacheKey());
if (alreadyInCache != null) {
return false;
}
// add the returning prepared statement to the cache.
// Note that the LRUCache will automatically close fully old unused
// PStmts when the cache has hit its maximum size.
put(pstmt.getCacheKey(), pstmt);
return true;
}
/**
* additionally maintains hit and miss statistics.
*/
public ExtendedPreparedStatement get(Object key) {
ExtendedPreparedStatement o = super.get(key);
if (o == null) {
missCounter++;
} else {
hitCounter++;
}
return o;
}
/**
* additionally maintains hit and miss statistics.
*/
public ExtendedPreparedStatement remove(Object key) {
ExtendedPreparedStatement o = super.remove(key);
if (o == null) {
missCounter++;
} else {
hitCounter++;
}
return o;
}
/**
* additionally maintains put counter statistics.
*/
public ExtendedPreparedStatement put(String key, ExtendedPreparedStatement value) {
putCounter++;
return super.put(key, value);
}
/**
* will check to see if we need to remove entries and
* if so call the cacheCleanup.cleanupEldestLRUCacheEntry() if
* one has been set.
*/
protected boolean removeEldestEntry(Map.Entry<String,ExtendedPreparedStatement> eldest) {
if (size() < maxSize) {
return false;
}
removeCounter++;
try {
ExtendedPreparedStatement pstmt = eldest.getValue();
pstmt.closeDestroy();
} catch (SQLException e) {
logger.error("Error closing ExtendedPreparedStatement", e);
}
return true;
}
}
@@ -1,106 +1,106 @@
package com.avaje.ebeaninternal.server.lib.sql;
import com.avaje.ebeaninternal.server.lib.util.MailEvent;
import com.avaje.ebeaninternal.server.lib.util.MailListener;
import com.avaje.ebeaninternal.server.lib.util.MailMessage;
import com.avaje.ebeaninternal.server.lib.util.MailSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A simple smtp email alert that sends a email message on dataSourceDown and
* dataSourceUp etc.
* <ul>
* <li>alert.fromuser = the from user name
* <li>alert.fromemail = the from email account
* <li>alert.toemail = comma delimited list of email accounts to email
* <li>alert.mailserver = the smpt server name
* </ul>
*/
public class SimpleDataSourceAlert implements DataSourceAlert, MailListener {
private static final Logger logger = LoggerFactory.getLogger(SimpleDataSourceAlert.class);
private static String alertMailServerName = System.getProperty("ebean.datasource.alert.mailserver");
private static String fromUser = System.getProperty("ebean.datasource.alert.fromUser");
private static String fromEmail = System.getProperty("ebean.datasource.alert.fromEmail");
private static String toEmail = System.getProperty("ebean.datasource.alert.toEmail");
/**
* Create a SimpleAlerter.
*/
public SimpleDataSourceAlert() {
}
/**
* If the email failed then log the error.
*/
public void handleEvent(MailEvent event) {
Throwable e = event.getError();
if (e != null) {
logger.error(null, e);
}
}
/**
* Send the dataSource down alert.
*/
@Override
public void dataSourceDown(String dataSourceName) {
String msg = getSubject(true, dataSourceName);
sendMessage(msg, msg);
}
/**
* Send the dataSource up alert.
*/
@Override
public void dataSourceUp(String dataSourceName) {
String msg = getSubject(false, dataSourceName);
sendMessage(msg, msg);
}
/**
* Send the warning message.
*/
@Override
public void dataSourceWarning(String subject, String msg) {
sendMessage(subject, msg);
}
private String getSubject(boolean isDown, String dsName) {
String msg = "The DataSource " + dsName;
if (isDown) {
msg += " is DOWN!!";
} else {
msg += " is UP.";
}
return msg;
}
private void sendMessage(String subject, String msg) {
if (alertMailServerName == null) {
return;
}
MailMessage data = new MailMessage();
data.setSender(fromUser, fromEmail);
data.addBodyLine(msg);
data.setSubject(subject);
String[] toList = toEmail.split(",");
if (toList.length == 0) {
logger.error("alert.toemail has not been set?");
} else {
for (int i = 0; i < toList.length; i++) {
data.addRecipient(null, toList[i].trim());
}
MailSender sender = new MailSender(alertMailServerName);
sender.setMailListener(this);
sender.sendInBackground(data);
}
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import com.avaje.ebeaninternal.server.lib.util.MailEvent;
import com.avaje.ebeaninternal.server.lib.util.MailListener;
import com.avaje.ebeaninternal.server.lib.util.MailMessage;
import com.avaje.ebeaninternal.server.lib.util.MailSender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A simple smtp email alert that sends a email message on dataSourceDown and
* dataSourceUp etc.
* <ul>
* <li>alert.fromuser = the from user name
* <li>alert.fromemail = the from email account
* <li>alert.toemail = comma delimited list of email accounts to email
* <li>alert.mailserver = the smpt server name
* </ul>
*/
public class SimpleDataSourceAlert implements DataSourceAlert, MailListener {
private static final Logger logger = LoggerFactory.getLogger(SimpleDataSourceAlert.class);
private static String alertMailServerName = System.getProperty("ebean.datasource.alert.mailserver");
private static String fromUser = System.getProperty("ebean.datasource.alert.fromUser");
private static String fromEmail = System.getProperty("ebean.datasource.alert.fromEmail");
private static String toEmail = System.getProperty("ebean.datasource.alert.toEmail");
/**
* Create a SimpleAlerter.
*/
public SimpleDataSourceAlert() {
}
/**
* If the email failed then log the error.
*/
public void handleEvent(MailEvent event) {
Throwable e = event.getError();
if (e != null) {
logger.error(null, e);
}
}
/**
* Send the dataSource down alert.
*/
@Override
public void dataSourceDown(String dataSourceName) {
String msg = getSubject(true, dataSourceName);
sendMessage(msg, msg);
}
/**
* Send the dataSource up alert.
*/
@Override
public void dataSourceUp(String dataSourceName) {
String msg = getSubject(false, dataSourceName);
sendMessage(msg, msg);
}
/**
* Send the warning message.
*/
@Override
public void dataSourceWarning(String subject, String msg) {
sendMessage(subject, msg);
}
private String getSubject(boolean isDown, String dsName) {
String msg = "The DataSource " + dsName;
if (isDown) {
msg += " is DOWN!!";
} else {
msg += " is UP.";
}
return msg;
}
private void sendMessage(String subject, String msg) {
if (alertMailServerName == null) {
return;
}
MailMessage data = new MailMessage();
data.setSender(fromUser, fromEmail);
data.addBodyLine(msg);
data.setSubject(subject);
String[] toList = toEmail.split(",");
if (toList.length == 0) {
logger.error("alert.toemail has not been set?");
} else {
for (int i = 0; i < toList.length; i++) {
data.addRecipient(null, toList[i].trim());
}
MailSender sender = new MailSender(alertMailServerName);
sender.setMailListener(this);
sender.sendInBackground(data);
}
}
}
@@ -1,69 +1,69 @@
package com.avaje.ebeaninternal.server.lib.sql;
import java.sql.Connection;
/**
* Helper object that can convert between transaction isolation descriptions and values.
*
*/
public class TransactionIsolation {
/**
* return the isolation level for a given string description.
*/
public static int getLevel(String level) {
level = level.toUpperCase();
if (level.startsWith("TRANSACTION")){
level = level.substring("TRANSACTION".length());
}
level = level.replace("_", "");
if ("NONE".equalsIgnoreCase(level)){
return Connection.TRANSACTION_NONE;
}
if ("READCOMMITTED".equalsIgnoreCase(level)){
return Connection.TRANSACTION_READ_COMMITTED;
}
if ("READUNCOMMITTED".equalsIgnoreCase(level)){
return Connection.TRANSACTION_READ_UNCOMMITTED;
}
if ("REPEATABLEREAD".equalsIgnoreCase(level)){
return Connection.TRANSACTION_REPEATABLE_READ;
}
if ("SERIALIZABLE".equalsIgnoreCase(level)){
return Connection.TRANSACTION_SERIALIZABLE;
}
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not known.");
}
/**
* Return the string description of the transaction isolation level specified.
* <p>Returned value is one of NONE, READ_COMMITTED,READ_UNCOMMITTED,
* REPEATABLE_READ or SERIALIZABLE.</p>
*
* @param level the transaction isolation level as per java.sql.Connection
* @return the level description as a string.
*/
public static String getLevelDescription(int level) {
switch (level) {
case Connection.TRANSACTION_NONE :
return "NONE";
case Connection.TRANSACTION_READ_COMMITTED :
return "READ_COMMITTED";
case Connection.TRANSACTION_READ_UNCOMMITTED :
return "READ_UNCOMMITTED";
case Connection.TRANSACTION_REPEATABLE_READ :
return "REPEATABLE_READ";
case Connection.TRANSACTION_SERIALIZABLE :
return "SERIALIZABLE";
case -1 :
return "NotSet";
default :
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not defined.");
}
}
}
package com.avaje.ebeaninternal.server.lib.sql;
import java.sql.Connection;
/**
* Helper object that can convert between transaction isolation descriptions and values.
*
*/
public class TransactionIsolation {
/**
* return the isolation level for a given string description.
*/
public static int getLevel(String level) {
level = level.toUpperCase();
if (level.startsWith("TRANSACTION")){
level = level.substring("TRANSACTION".length());
}
level = level.replace("_", "");
if ("NONE".equalsIgnoreCase(level)){
return Connection.TRANSACTION_NONE;
}
if ("READCOMMITTED".equalsIgnoreCase(level)){
return Connection.TRANSACTION_READ_COMMITTED;
}
if ("READUNCOMMITTED".equalsIgnoreCase(level)){
return Connection.TRANSACTION_READ_UNCOMMITTED;
}
if ("REPEATABLEREAD".equalsIgnoreCase(level)){
return Connection.TRANSACTION_REPEATABLE_READ;
}
if ("SERIALIZABLE".equalsIgnoreCase(level)){
return Connection.TRANSACTION_SERIALIZABLE;
}
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not known.");
}
/**
* Return the string description of the transaction isolation level specified.
* <p>Returned value is one of NONE, READ_COMMITTED,READ_UNCOMMITTED,
* REPEATABLE_READ or SERIALIZABLE.</p>
*
* @param level the transaction isolation level as per java.sql.Connection
* @return the level description as a string.
*/
public static String getLevelDescription(int level) {
switch (level) {
case Connection.TRANSACTION_NONE :
return "NONE";
case Connection.TRANSACTION_READ_COMMITTED :
return "READ_COMMITTED";
case Connection.TRANSACTION_READ_UNCOMMITTED :
return "READ_UNCOMMITTED";
case Connection.TRANSACTION_REPEATABLE_READ :
return "REPEATABLE_READ";
case Connection.TRANSACTION_SERIALIZABLE :
return "SERIALIZABLE";
case -1 :
return "NotSet";
default :
throw new RuntimeException("Transaction Isolaction level [" + level + "] is not defined.");
}
}
}
@@ -1,23 +1,23 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception when creating an Object.
*/
public class CreateObjectException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539736L;
public CreateObjectException(Exception cause) {
super(cause);
}
public CreateObjectException(String s, Exception cause) {
super(s, cause);
}
public CreateObjectException(String s) {
super(s);
}
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception when creating an Object.
*/
public class CreateObjectException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539736L;
public CreateObjectException(Exception cause) {
super(cause);
}
public CreateObjectException(String s, Exception cause) {
super(s, cause);
}
public CreateObjectException(String s) {
super(s);
}
}
@@ -1,324 +1,324 @@
package com.avaje.ebeaninternal.server.lib.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
/**
* A lightweight tree structure for simple XML handling.
* <p>
* It removes support for nodes being mixed with content. That is, a node can
* only contain content or a list of one or more child nodes. It does not
* support mixing bits of content between the child nodes.
* </p>
* <p>
* Although designed to simplify XML in supported cases it can be used as a
* general tree structure with attributes of java Objects.
* </p>
*/
public class Dnode {
int level;
String nodeName;
String nodeContent;
ArrayList<Dnode> children;
LinkedHashMap<String, String> attrList = new LinkedHashMap<String, String>();
/**
* Create a node.
*/
public Dnode() {
}
/**
* Parse the raw XML string.
*/
public static Dnode parse(String s){
DnodeReader r = new DnodeReader();
return r.parseXml(s);
}
/**
* Return the node as XML.
*/
public String toXml() {
StringBuilder sb = new StringBuilder();
generate(sb);
return sb.toString();
}
/**
* Generate this node as xml to the buffer.
*/
public StringBuilder generate(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append("<").append(nodeName);
for (String attr : attrList.keySet()) {
Object attrValue = getAttribute(attr);
sb.append(" ").append(attr).append("=\"");
if (attrValue != null) {
sb.append(attrValue);
}
sb.append("\"");
}
if (nodeContent == null && !hasChildren()) {
sb.append(" />");
} else {
sb.append(">");
if (children != null && children.size() > 0) {
for (int i = 0; i < children.size(); i++) {
Dnode child = children.get(i);
child.generate(sb);
}
}
if (nodeContent != null) {
sb.append(nodeContent);
}
sb.append("</").append(nodeName).append(">");
}
return sb;
}
/**
* Return the node name.
*/
public String getNodeName() {
return nodeName;
}
/**
* Set the node name.
*/
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
/**
* Return the node content.
*/
public String getNodeContent() {
return nodeContent;
}
/**
* Set the node content.
*/
public void setNodeContent(String nodeContent) {
this.nodeContent = nodeContent;
}
/**
* Return true if this node has children.
*/
public boolean hasChildren() {
return getChildrenCount() > 0;
}
/**
* Return the number of children this node has.
*/
public int getChildrenCount() {
if (children == null) {
return 0;
}
return children.size();
}
/**
* Remove a ancestor node.
*/
public boolean remove(Dnode node) {
if (children == null) {
return false;
}
if (children.remove(node)) {
return true;
}
for (Dnode child : children) {
if (child.remove(node)) {
return true;
}
}
return false;
}
/**
* List of children nodes.
*/
public List<Dnode> children() {
if (children == null) {
return null;
}
return children;
}
/**
* Add a child.
*/
public void addChild(Dnode child) {
if (children == null) {
children = new ArrayList<Dnode>();
}
children.add(child);
child.setLevel(level + 1);
}
/**
* Return the level or depth of the node from the root.
*/
public int getLevel() {
return level;
}
/**
* Set the level or depth of this node from the root.
*/
public void setLevel(int level) {
this.level = level;
if (children != null) {
for (int i = 0; i < children.size(); i++) {
Dnode child = children.get(i);
child.setLevel(level + 1);
}
}
}
/**
* Find the first matching node using nodeName. This is a depth first tree
* search.
*/
public Dnode find(String nodeName) {
return find(nodeName, null, null);
}
/**
* Find the first node matching nodeName and attribute value. This is a
* depth first tree search.
*/
public Dnode find(String nodeName, String attrName, Object value) {
return find(nodeName, attrName, value, -1);
}
/**
* Search for a single node with control over maxLevel. Find the first node
* matching nodeName and attribute value. If attrName and value are null
* then this will just search using the nodeName. This is a depth first tree
* search. Once a matching node is found the search will stop.
*/
public Dnode find(String nodeName, String attrName, Object value, int maxLevel) {
ArrayList<Dnode> list = new ArrayList<Dnode>();
findByNode(list, nodeName, true, attrName, value, maxLevel);
if (list.size() >= 1) {
return list.get(0);
}
return null;
}
/**
* Find all the nodes that match the nodeName.
*
*/
public List<Dnode> findAll(String nodeName, int maxLevel) {
int level = -1;
if (maxLevel > 0) {
level = this.level + maxLevel;
}
return findAll(nodeName, null, null, level);
}
/**
* Find all the nodes that match the nodeName and attribute value.
*/
public List<Dnode> findAll(String nodeName, String attrName, Object value, int maxLevel) {
if (nodeName == null && attrName == null) {
throw new RuntimeException("You can not have both nodeName and attrName null");
}
ArrayList<Dnode> list = new ArrayList<Dnode>();
findByNode(list, nodeName, false, attrName, value, maxLevel);
return list;
}
/**
* Used for recursive calling.
*/
private void findByNode(List<Dnode> list, String node, boolean findOne,String attrName, Object value, int maxLevel) {
if (findOne && list.size() == 1) {
return;
}
if (node == null || node.equals(nodeName)) {
if (attrName == null || value.equals(getAttribute(attrName))) {
list.add(this);
if (findOne) {
return;
}
}
}
if (maxLevel > 0 && level >= maxLevel) {
// hit max level
} else if (children != null) {
// recursively search the children
for (int i = 0; i < children.size(); i++) {
Dnode child = children.get(i);
child.findByNode(list, node, findOne, attrName, value,maxLevel);
}
}
}
/**
* The attribute names as strings.
*/
public Collection<String> attributeNames() {
return attrList.keySet();
}
/**
* Return the attribute for a given name.
*/
public String getAttribute(String name) {
return attrList.get(name);
}
/**
* Returns an Attribute as a String.
* <p>
* Will throw a ClassCastException if the attribute is not a String.
* </p>
*/
public String getStringAttr(String name, String defaultValue) {
Object o = attrList.get(name);
if (o == null){
return defaultValue;
} else {
return o.toString();
}
}
/**
* Set an attribute.
*/
public void setAttribute(String name, String value) {
attrList.put(name, value);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[").append(getNodeName()).append(" ").append(attrList).append("]");
return sb.toString();
}
}
package com.avaje.ebeaninternal.server.lib.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
/**
* A lightweight tree structure for simple XML handling.
* <p>
* It removes support for nodes being mixed with content. That is, a node can
* only contain content or a list of one or more child nodes. It does not
* support mixing bits of content between the child nodes.
* </p>
* <p>
* Although designed to simplify XML in supported cases it can be used as a
* general tree structure with attributes of java Objects.
* </p>
*/
public class Dnode {
int level;
String nodeName;
String nodeContent;
ArrayList<Dnode> children;
LinkedHashMap<String, String> attrList = new LinkedHashMap<String, String>();
/**
* Create a node.
*/
public Dnode() {
}
/**
* Parse the raw XML string.
*/
public static Dnode parse(String s){
DnodeReader r = new DnodeReader();
return r.parseXml(s);
}
/**
* Return the node as XML.
*/
public String toXml() {
StringBuilder sb = new StringBuilder();
generate(sb);
return sb.toString();
}
/**
* Generate this node as xml to the buffer.
*/
public StringBuilder generate(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append("<").append(nodeName);
for (String attr : attrList.keySet()) {
Object attrValue = getAttribute(attr);
sb.append(" ").append(attr).append("=\"");
if (attrValue != null) {
sb.append(attrValue);
}
sb.append("\"");
}
if (nodeContent == null && !hasChildren()) {
sb.append(" />");
} else {
sb.append(">");
if (children != null && children.size() > 0) {
for (int i = 0; i < children.size(); i++) {
Dnode child = children.get(i);
child.generate(sb);
}
}
if (nodeContent != null) {
sb.append(nodeContent);
}
sb.append("</").append(nodeName).append(">");
}
return sb;
}
/**
* Return the node name.
*/
public String getNodeName() {
return nodeName;
}
/**
* Set the node name.
*/
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
/**
* Return the node content.
*/
public String getNodeContent() {
return nodeContent;
}
/**
* Set the node content.
*/
public void setNodeContent(String nodeContent) {
this.nodeContent = nodeContent;
}
/**
* Return true if this node has children.
*/
public boolean hasChildren() {
return getChildrenCount() > 0;
}
/**
* Return the number of children this node has.
*/
public int getChildrenCount() {
if (children == null) {
return 0;
}
return children.size();
}
/**
* Remove a ancestor node.
*/
public boolean remove(Dnode node) {
if (children == null) {
return false;
}
if (children.remove(node)) {
return true;
}
for (Dnode child : children) {
if (child.remove(node)) {
return true;
}
}
return false;
}
/**
* List of children nodes.
*/
public List<Dnode> children() {
if (children == null) {
return null;
}
return children;
}
/**
* Add a child.
*/
public void addChild(Dnode child) {
if (children == null) {
children = new ArrayList<Dnode>();
}
children.add(child);
child.setLevel(level + 1);
}
/**
* Return the level or depth of the node from the root.
*/
public int getLevel() {
return level;
}
/**
* Set the level or depth of this node from the root.
*/
public void setLevel(int level) {
this.level = level;
if (children != null) {
for (int i = 0; i < children.size(); i++) {
Dnode child = children.get(i);
child.setLevel(level + 1);
}
}
}
/**
* Find the first matching node using nodeName. This is a depth first tree
* search.
*/
public Dnode find(String nodeName) {
return find(nodeName, null, null);
}
/**
* Find the first node matching nodeName and attribute value. This is a
* depth first tree search.
*/
public Dnode find(String nodeName, String attrName, Object value) {
return find(nodeName, attrName, value, -1);
}
/**
* Search for a single node with control over maxLevel. Find the first node
* matching nodeName and attribute value. If attrName and value are null
* then this will just search using the nodeName. This is a depth first tree
* search. Once a matching node is found the search will stop.
*/
public Dnode find(String nodeName, String attrName, Object value, int maxLevel) {
ArrayList<Dnode> list = new ArrayList<Dnode>();
findByNode(list, nodeName, true, attrName, value, maxLevel);
if (list.size() >= 1) {
return list.get(0);
}
return null;
}
/**
* Find all the nodes that match the nodeName.
*
*/
public List<Dnode> findAll(String nodeName, int maxLevel) {
int level = -1;
if (maxLevel > 0) {
level = this.level + maxLevel;
}
return findAll(nodeName, null, null, level);
}
/**
* Find all the nodes that match the nodeName and attribute value.
*/
public List<Dnode> findAll(String nodeName, String attrName, Object value, int maxLevel) {
if (nodeName == null && attrName == null) {
throw new RuntimeException("You can not have both nodeName and attrName null");
}
ArrayList<Dnode> list = new ArrayList<Dnode>();
findByNode(list, nodeName, false, attrName, value, maxLevel);
return list;
}
/**
* Used for recursive calling.
*/
private void findByNode(List<Dnode> list, String node, boolean findOne,String attrName, Object value, int maxLevel) {
if (findOne && list.size() == 1) {
return;
}
if (node == null || node.equals(nodeName)) {
if (attrName == null || value.equals(getAttribute(attrName))) {
list.add(this);
if (findOne) {
return;
}
}
}
if (maxLevel > 0 && level >= maxLevel) {
// hit max level
} else if (children != null) {
// recursively search the children
for (int i = 0; i < children.size(); i++) {
Dnode child = children.get(i);
child.findByNode(list, node, findOne, attrName, value,maxLevel);
}
}
}
/**
* The attribute names as strings.
*/
public Collection<String> attributeNames() {
return attrList.keySet();
}
/**
* Return the attribute for a given name.
*/
public String getAttribute(String name) {
return attrList.get(name);
}
/**
* Returns an Attribute as a String.
* <p>
* Will throw a ClassCastException if the attribute is not a String.
* </p>
*/
public String getStringAttr(String name, String defaultValue) {
Object o = attrList.get(name);
if (o == null){
return defaultValue;
} else {
return o.toString();
}
}
/**
* Set an attribute.
*/
public void setAttribute(String name, String value) {
attrList.put(name, value);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[").append(getNodeName()).append(" ").append(attrList).append("]");
return sb.toString();
}
}
@@ -1,200 +1,200 @@
package com.avaje.ebeaninternal.server.lib.util;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Parse an xml document into a Dnode tree.
*/
public class DnodeParser extends DefaultHandler {
/**
* The root of the DContent tree.
*/
Dnode root;
/**
* The current node being parsed.
*/
Dnode currentNode;
/**
* The nodeContent buffer.
*/
StringBuilder buffer;
/**
* Used to stack the nodes.
*/
Stack<Dnode> stack = new Stack<Dnode>();
/**
* The class used to construct new nodes. Should be Dnode or a subtype of
* Dnode.
*/
Class<?> nodeClass = Dnode.class;
int depth = 0;
/**
* Trim whitespace from the content.
*/
boolean trimWhitespace = true;
/**
* The name of the tag that contains html content
*/
String contentName;
/**
* The depth of the tag that contains the html content
*/
int contentDepth;
/**
* If true then trim the whitespace from the content.
*/
public boolean isTrimWhitespace() {
return trimWhitespace;
}
/**
* Set whether to trim whitespace from the content.
*/
public void setTrimWhitespace(boolean trimWhitespace) {
this.trimWhitespace = trimWhitespace;
}
/**
* Return the root node of the DContent tree.
*/
public Dnode getRoot() {
return root;
}
/**
* Set the type class of node to be created.
*/
public void setNodeClass(Class<?> nodeClass) {
this.nodeClass = nodeClass;
}
/**
* Create a new Dnode using the nodeClass.
*/
private Dnode createNewNode() {
try {
return (Dnode) nodeClass.newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* process a startElement.
*/
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
super.startElement(uri, localName, qName, attributes);
depth++;
boolean isContent = (contentName != null);
if (isContent){
// must be html content... add the begin tag as content
buffer.append("<").append(localName);
for (int i = 0; i < attributes.getLength(); i++) {
String key = attributes.getLocalName(i);
String val = attributes.getValue(i);
buffer.append(" ").append(key).append("='").append(val).append("'");
}
buffer.append(">");
return;
}
buffer = new StringBuilder();
Dnode node = createNewNode();
node.setNodeName(localName);
for (int i = 0; i < attributes.getLength(); i++) {
String key = attributes.getLocalName(i);
String val = attributes.getValue(i);
node.setAttribute(key, val);
if ("type".equalsIgnoreCase(key) && "content".equalsIgnoreCase(val)) {
// this tag contains html content
// no more nodes until end tag is found
contentName = localName;
contentDepth = depth-1;
}
}
if (root == null) {
root = node;
}
if (currentNode != null) {
currentNode.addChild(node);
}
stack.push(node);
currentNode = node;
}
/**
* append the node content.
*/
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
String s = new String(ch, start, length);
int p = s.indexOf('\r');
int p2 = s.indexOf('\n');
if (p == -1 && p2 > -1) {
// This is probably not an issue but tidys up content
// in my text editor
s = StringHelper.replaceString(s, "\n", "\r\n");
}
buffer.append(s);
}
/**
* process the endElement.
*/
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
depth--;
if (contentName != null){
// is this the end of the content?
if (contentName.equals(localName) && contentDepth == depth){
contentName = null;
} else {
// the html content end tag
buffer.append("</").append(localName).append(">");
}
return;
}
String content = buffer.toString();
buffer.setLength(0);
if (content.length() > 0) {
if (trimWhitespace) {
content = content.trim();
}
if (content.length() > 0) {
currentNode.setNodeContent(content);
}
}
stack.pop();
if (!stack.isEmpty()) {
// get the new currentNode
currentNode = (Dnode) stack.pop();
stack.push(currentNode);
}
}
}
package com.avaje.ebeaninternal.server.lib.util;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Parse an xml document into a Dnode tree.
*/
public class DnodeParser extends DefaultHandler {
/**
* The root of the DContent tree.
*/
Dnode root;
/**
* The current node being parsed.
*/
Dnode currentNode;
/**
* The nodeContent buffer.
*/
StringBuilder buffer;
/**
* Used to stack the nodes.
*/
Stack<Dnode> stack = new Stack<Dnode>();
/**
* The class used to construct new nodes. Should be Dnode or a subtype of
* Dnode.
*/
Class<?> nodeClass = Dnode.class;
int depth = 0;
/**
* Trim whitespace from the content.
*/
boolean trimWhitespace = true;
/**
* The name of the tag that contains html content
*/
String contentName;
/**
* The depth of the tag that contains the html content
*/
int contentDepth;
/**
* If true then trim the whitespace from the content.
*/
public boolean isTrimWhitespace() {
return trimWhitespace;
}
/**
* Set whether to trim whitespace from the content.
*/
public void setTrimWhitespace(boolean trimWhitespace) {
this.trimWhitespace = trimWhitespace;
}
/**
* Return the root node of the DContent tree.
*/
public Dnode getRoot() {
return root;
}
/**
* Set the type class of node to be created.
*/
public void setNodeClass(Class<?> nodeClass) {
this.nodeClass = nodeClass;
}
/**
* Create a new Dnode using the nodeClass.
*/
private Dnode createNewNode() {
try {
return (Dnode) nodeClass.newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* process a startElement.
*/
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
super.startElement(uri, localName, qName, attributes);
depth++;
boolean isContent = (contentName != null);
if (isContent){
// must be html content... add the begin tag as content
buffer.append("<").append(localName);
for (int i = 0; i < attributes.getLength(); i++) {
String key = attributes.getLocalName(i);
String val = attributes.getValue(i);
buffer.append(" ").append(key).append("='").append(val).append("'");
}
buffer.append(">");
return;
}
buffer = new StringBuilder();
Dnode node = createNewNode();
node.setNodeName(localName);
for (int i = 0; i < attributes.getLength(); i++) {
String key = attributes.getLocalName(i);
String val = attributes.getValue(i);
node.setAttribute(key, val);
if ("type".equalsIgnoreCase(key) && "content".equalsIgnoreCase(val)) {
// this tag contains html content
// no more nodes until end tag is found
contentName = localName;
contentDepth = depth-1;
}
}
if (root == null) {
root = node;
}
if (currentNode != null) {
currentNode.addChild(node);
}
stack.push(node);
currentNode = node;
}
/**
* append the node content.
*/
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
String s = new String(ch, start, length);
int p = s.indexOf('\r');
int p2 = s.indexOf('\n');
if (p == -1 && p2 > -1) {
// This is probably not an issue but tidys up content
// in my text editor
s = StringHelper.replaceString(s, "\n", "\r\n");
}
buffer.append(s);
}
/**
* process the endElement.
*/
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
depth--;
if (contentName != null){
// is this the end of the content?
if (contentName.equals(localName) && contentDepth == depth){
contentName = null;
} else {
// the html content end tag
buffer.append("</").append(localName).append(">");
}
return;
}
String content = buffer.toString();
buffer.setLength(0);
if (content.length() > 0) {
if (trimWhitespace) {
content = content.trim();
}
if (content.length() > 0) {
currentNode.setNodeContent(content);
}
}
stack.pop();
if (!stack.isEmpty()) {
// get the new currentNode
currentNode = (Dnode) stack.pop();
stack.push(currentNode);
}
}
}
@@ -1,70 +1,70 @@
package com.avaje.ebeaninternal.server.lib.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* Parses an XML inputstream returning a Dnode tree.
*/
public class DnodeReader {
public Dnode parseXml(String str) {
try {
ByteArrayOutputStream bao = new ByteArrayOutputStream(str.length());
OutputStreamWriter osw = new OutputStreamWriter(bao);
StringReader sr = new StringReader(str);
int charBufferSize = 1024;
char[] buf = new char[charBufferSize];
int len;
while ((len = sr.read(buf, 0, buf.length)) != -1) {
osw.write(buf, 0, len);
}
sr.close();
osw.flush();
osw.close();
bao.flush();
bao.close();
InputStream is = new ByteArrayInputStream(bao.toByteArray());
return parseXml(is);
} catch (IOException ex){
throw new RuntimeException(ex);
}
}
/**
* Parse the XML inputstream returning the Dnode tree.
*/
public Dnode parseXml(InputStream in) {
try {
InputSource inSource = new InputSource(in);
DnodeParser parser = new DnodeParser();
XMLReader myReader = XMLReaderFactory.createXMLReader();
myReader.setContentHandler(parser);
myReader.parse(inSource);
return parser.getRoot();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package com.avaje.ebeaninternal.server.lib.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* Parses an XML inputstream returning a Dnode tree.
*/
public class DnodeReader {
public Dnode parseXml(String str) {
try {
ByteArrayOutputStream bao = new ByteArrayOutputStream(str.length());
OutputStreamWriter osw = new OutputStreamWriter(bao);
StringReader sr = new StringReader(str);
int charBufferSize = 1024;
char[] buf = new char[charBufferSize];
int len;
while ((len = sr.read(buf, 0, buf.length)) != -1) {
osw.write(buf, 0, len);
}
sr.close();
osw.flush();
osw.close();
bao.flush();
bao.close();
InputStream is = new ByteArrayInputStream(bao.toByteArray());
return parseXml(is);
} catch (IOException ex){
throw new RuntimeException(ex);
}
}
/**
* Parse the XML inputstream returning the Dnode tree.
*/
public Dnode parseXml(InputStream in) {
try {
InputSource inSource = new InputSource(in);
DnodeParser parser = new DnodeParser();
XMLReader myReader = XMLReaderFactory.createXMLReader();
myReader.setContentHandler(parser);
myReader.parse(inSource);
return parser.getRoot();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -1,22 +1,22 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception that can be used for multiple purposes.
*/
public class GeneralException extends RuntimeException {
private static final long serialVersionUID = 5783084420007103280L;
public GeneralException(Exception cause) {
super(cause);
}
public GeneralException(String s, Exception cause) {
super(s, cause);
}
public GeneralException(String s) {
super(s);
}
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception that can be used for multiple purposes.
*/
public class GeneralException extends RuntimeException {
private static final long serialVersionUID = 5783084420007103280L;
public GeneralException(Exception cause) {
super(cause);
}
public GeneralException(String s, Exception cause) {
super(s, cause);
}
public GeneralException(String s) {
super(s);
}
}
@@ -1,23 +1,23 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception for invalid data.
*/
public class InvalidDataException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539846L;
public InvalidDataException(Exception cause) {
super(cause);
}
public InvalidDataException(String s, Exception cause) {
super(s, cause);
}
public InvalidDataException(String s) {
super(s);
}
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception for invalid data.
*/
public class InvalidDataException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539846L;
public InvalidDataException(Exception cause) {
super(cause);
}
public InvalidDataException(String s, Exception cause) {
super(s, cause);
}
public InvalidDataException(String s) {
super(s);
}
}
@@ -1,45 +1,45 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* An Email address with an associated alias.
*/
public class MailAddress {
String alias;
String emailAddress;
/**
* Create an address with an optional alias.
*/
public MailAddress(String alias, String emailAddress){
this.alias = alias;
this.emailAddress = emailAddress;
}
/**
* Return the alias.
* If the alias is null this returns an empty string.
*/
public String getAlias() {
if (alias == null){
return "";
}
return alias;
}
/**
* Return the email address.
*/
public String getEmailAddress(){
return emailAddress;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getAlias()).append(" ").append("<").append(getEmailAddress()).append(">");
return sb.toString();
}
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* An Email address with an associated alias.
*/
public class MailAddress {
String alias;
String emailAddress;
/**
* Create an address with an optional alias.
*/
public MailAddress(String alias, String emailAddress){
this.alias = alias;
this.emailAddress = emailAddress;
}
/**
* Return the alias.
* If the alias is null this returns an empty string.
*/
public String getAlias() {
if (alias == null){
return "";
}
return alias;
}
/**
* Return the email address.
*/
public String getEmailAddress(){
return emailAddress;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getAlias()).append(" ").append("<").append(getEmailAddress()).append(">");
return sb.toString();
}
}
@@ -1,49 +1,49 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* Represents the success or failure of a mail send.
*/
public class MailEvent {
/**
* The error indicating a send failure.
*/
Throwable error;
/**
* The message that was sent.
*/
MailMessage message;
/**
* The message send failed with an error.
*/
public MailEvent(MailMessage message, Throwable error){
this.message = message;
this.error = error;
}
/**
* The message that we attempted to send.
*/
public MailMessage getMailMessage() {
return message;
}
/**
* Returns true if the message was sent successfully.
*/
public boolean wasSuccessful() {
return (error == null);
}
/**
* The error indicating the send failed.
*/
public Throwable getError() {
return error;
}
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* Represents the success or failure of a mail send.
*/
public class MailEvent {
/**
* The error indicating a send failure.
*/
Throwable error;
/**
* The message that was sent.
*/
MailMessage message;
/**
* The message send failed with an error.
*/
public MailEvent(MailMessage message, Throwable error){
this.message = message;
this.error = error;
}
/**
* The message that we attempted to send.
*/
public MailMessage getMailMessage() {
return message;
}
/**
* Returns true if the message was sent successfully.
*/
public boolean wasSuccessful() {
return (error == null);
}
/**
* The error indicating the send failed.
*/
public Throwable getError() {
return error;
}
}
@@ -1,13 +1,13 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* Listens to see if the message was successfully sent.
*/
public interface MailListener {
/**
* Handle the message event.
*/
public void handleEvent(MailEvent event);
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* Listens to see if the message was successfully sent.
*/
public interface MailListener {
/**
* Handle the message event.
*/
public void handleEvent(MailEvent event);
}
@@ -1,157 +1,157 @@
package com.avaje.ebeaninternal.server.lib.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
* A simple test message that can be sent via smtp.
*/
public class MailMessage {
// /**
// * The subject text.
// */
// String subject;
/**
* The body content.
*/
ArrayList<String> bodylines;
/**
* The sender email address.
*/
MailAddress senderAddress;
/**
* The headers.
*/
HashMap<String,String> header = new HashMap<String, String>();
/**
* the recipient of the email.
*/
MailAddress currentRecipient;
/**
* The list of recipients.
*/
ArrayList<MailAddress> recipientList = new ArrayList<MailAddress>();
/**
* Create the message.
*/
public MailMessage() {
bodylines = new ArrayList<String>();
}
/**
* Set the current recipient.
*/
public void setCurrentRecipient(MailAddress currentRecipient){
this.currentRecipient = currentRecipient;
}
/**
* Return the current recipient.
*/
public MailAddress getCurrentRecipient() {
return currentRecipient;
}
/**
* Add a recipient.
*/
public void addRecipient(String alias, String emailAddress){
recipientList.add(new MailAddress(alias, emailAddress));
}
/**
* Set the sender details.
*/
public void setSender(String alias, String senderEmail){
this.senderAddress = new MailAddress(alias, senderEmail);
}
/**
* Return the sender address.
*/
public MailAddress getSender() {
return senderAddress;
}
/**
* Return the recipient list.
*/
public List<MailAddress> getRecipientList() {
return recipientList;
}
/**
* add a header to the message.
*/
public void addHeader(String key, String val) {
header.put(key, val);
}
/**
* Set the subject text.
*/
public void setSubject(String subject){
addHeader("Subject", subject);
}
/**
* Return the subject text.
*/
public String getSubject() {
return getHeader("Subject");
}
/**
* Add text to the body.
*/
public void addBodyLine(String line) {
bodylines.add(line);
}
/**
* Return the body text.
*/
public List<String> getBodyLines() {
return bodylines;
}
/**
* Return the headers.
*/
public Collection<String> getHeaderFields() {
return header.keySet();
}
/**
* Return a given header.
*/
public String getHeader(String key) {
return header.get(key);
}
public String toString() {
StringBuilder sb = new StringBuilder(100);
sb.append("Sender: " + senderAddress + "\tRecipient: " + recipientList + "\n");
for (String key : header.keySet()) {
String hline = key + ": " + header.get(key) + "\n";
sb.append(hline);
}
sb.append("\n");
for (String line : bodylines) {
sb.append(line).append("\n");
}
return sb.toString();
}
}
package com.avaje.ebeaninternal.server.lib.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
* A simple test message that can be sent via smtp.
*/
public class MailMessage {
// /**
// * The subject text.
// */
// String subject;
/**
* The body content.
*/
ArrayList<String> bodylines;
/**
* The sender email address.
*/
MailAddress senderAddress;
/**
* The headers.
*/
HashMap<String,String> header = new HashMap<String, String>();
/**
* the recipient of the email.
*/
MailAddress currentRecipient;
/**
* The list of recipients.
*/
ArrayList<MailAddress> recipientList = new ArrayList<MailAddress>();
/**
* Create the message.
*/
public MailMessage() {
bodylines = new ArrayList<String>();
}
/**
* Set the current recipient.
*/
public void setCurrentRecipient(MailAddress currentRecipient){
this.currentRecipient = currentRecipient;
}
/**
* Return the current recipient.
*/
public MailAddress getCurrentRecipient() {
return currentRecipient;
}
/**
* Add a recipient.
*/
public void addRecipient(String alias, String emailAddress){
recipientList.add(new MailAddress(alias, emailAddress));
}
/**
* Set the sender details.
*/
public void setSender(String alias, String senderEmail){
this.senderAddress = new MailAddress(alias, senderEmail);
}
/**
* Return the sender address.
*/
public MailAddress getSender() {
return senderAddress;
}
/**
* Return the recipient list.
*/
public List<MailAddress> getRecipientList() {
return recipientList;
}
/**
* add a header to the message.
*/
public void addHeader(String key, String val) {
header.put(key, val);
}
/**
* Set the subject text.
*/
public void setSubject(String subject){
addHeader("Subject", subject);
}
/**
* Return the subject text.
*/
public String getSubject() {
return getHeader("Subject");
}
/**
* Add text to the body.
*/
public void addBodyLine(String line) {
bodylines.add(line);
}
/**
* Return the body text.
*/
public List<String> getBodyLines() {
return bodylines;
}
/**
* Return the headers.
*/
public Collection<String> getHeaderFields() {
return header.keySet();
}
/**
* Return a given header.
*/
public String getHeader(String key) {
return header.get(key);
}
public String toString() {
StringBuilder sb = new StringBuilder(100);
sb.append("Sender: " + senderAddress + "\tRecipient: " + recipientList + "\n");
for (String key : header.keySet()) {
String hline = key + ": " + header.get(key) + "\n";
sb.append(hline);
}
sb.append("\n");
for (String line : bodylines) {
sb.append(line).append("\n");
}
return sb.toString();
}
}
@@ -1,206 +1,206 @@
package com.avaje.ebeaninternal.server.lib.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Sends simple MailMessages via smtp.
*/
public class MailSender implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(MailSender.class);
int traceLevel = 0;
Socket sserver;
String server;
BufferedReader in;
OutputStreamWriter out;
MailMessage message;
MailListener listener = null;
private static final int SMTP_PORT = 25;
/**
* Create for a given mail server.
*/
public MailSender(String server) {
this.server = server;
}
/**
* Set the listener to handle MessageEvents.
*/
public void setMailListener(MailListener listener) {
this.listener = listener;
}
/**
* Send the message.
*/
public void run() {
send(message);
}
/**
* Send the message in a background thread.
*/
public void sendInBackground(MailMessage message) {
this.message = message;
Thread thread = new Thread(this);
thread.start();
}
/**
* Send the message in the current thread.
*/
public void send(MailMessage message) {
try {
for (MailAddress recipientAddress : message.getRecipientList()) {
sserver = new Socket(server, SMTP_PORT);
send(message, sserver, recipientAddress);
sserver.close();
if (listener != null) {
MailEvent event = new MailEvent(message, null);
listener.handleEvent(event);
}
}
} catch (Exception ex) {
if (listener != null) {
MailEvent event = new MailEvent(message, ex);
listener.handleEvent(event);
} else {
logger.error(null, ex);
}
}
}
private void send(MailMessage message, Socket sserver, MailAddress recipientAddress) throws IOException {
// A bit convoluted, but doesn't depend on DNS in any way...
InetAddress localhost = sserver.getLocalAddress();
String localaddress = localhost.getHostAddress();
MailAddress sender = message.getSender();
message.setCurrentRecipient(recipientAddress);
// Mandatory header fields, Date and From
if (message.getHeader("Date") == null) {
message.addHeader("Date", new java.util.Date().toString());
}
if (message.getHeader("From") == null) {
message.addHeader("From", sender.getAlias() + " <" + sender.getEmailAddress() + ">");
}
// if (message.getHeader("From") == null){
message.addHeader("To", recipientAddress.getAlias() + " <" + recipientAddress.getEmailAddress() + ">");
// }
out = new OutputStreamWriter(sserver.getOutputStream());
in = new BufferedReader(new InputStreamReader(sserver.getInputStream()));
String sintro = readln();
if (!sintro.startsWith("220")) { // 220
logger.debug("SmtpSender: intro==" + sintro);
return;
}
writeln("EHLO " + localaddress);
if (!expect250()) {
return;
}
writeln("MAIL FROM:<" + sender.getEmailAddress() + ">");
if (!expect250()) {
return;
}
writeln("RCPT TO:<" + recipientAddress.getEmailAddress() + ">");
if (!expect250()) {
return;
}
writeln("DATA");
while (true) { // may be multiple 250 replies pending from server
String line = readln();
if (line.startsWith("3"))
break; // ready to send
if (!line.startsWith("2")) {
logger.debug("SmtpSender.send reponse to DATA: " + line);
return;
}
}
for (String key : message.getHeaderFields()) {
writeln(key + ": " + message.getHeader(key));
}
writeln(""); // end of header;
for (String bline : message.getBodyLines()) {
if (bline.startsWith(".")) {
bline = "." + bline;
}
writeln(bline);
}
writeln(".");
expect250();
writeln("QUIT");
}
private boolean expect250() throws IOException {
String line = readln();
if (!line.startsWith("2")) {
logger.info("SmtpSender.expect250: " + line);
return false;
}
return true;
}
private void writeln(String s) throws IOException {
if (traceLevel > 2) {
logger.debug("From client: " + s);
}
out.write(s + "\r\n");
out.flush();
}
private String readln() throws IOException {
String line = in.readLine();
if (traceLevel > 1) {
logger.debug("From server: " + line);
}
return line;
}
/**
* Set the trace level.
*/
public void setTraceLevel(int traceLevel) {
this.traceLevel = traceLevel;
}
/**
* Return the hostname of the local machine.
*/
public String getLocalHostName() {
try {
InetAddress ipaddress = InetAddress.getLocalHost();
String localHost = ipaddress.getHostName();
if (localHost == null) {
return "localhost";
} else {
return localHost;
}
} catch (UnknownHostException e) {
return "localhost";
}
}
}
package com.avaje.ebeaninternal.server.lib.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Sends simple MailMessages via smtp.
*/
public class MailSender implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(MailSender.class);
int traceLevel = 0;
Socket sserver;
String server;
BufferedReader in;
OutputStreamWriter out;
MailMessage message;
MailListener listener = null;
private static final int SMTP_PORT = 25;
/**
* Create for a given mail server.
*/
public MailSender(String server) {
this.server = server;
}
/**
* Set the listener to handle MessageEvents.
*/
public void setMailListener(MailListener listener) {
this.listener = listener;
}
/**
* Send the message.
*/
public void run() {
send(message);
}
/**
* Send the message in a background thread.
*/
public void sendInBackground(MailMessage message) {
this.message = message;
Thread thread = new Thread(this);
thread.start();
}
/**
* Send the message in the current thread.
*/
public void send(MailMessage message) {
try {
for (MailAddress recipientAddress : message.getRecipientList()) {
sserver = new Socket(server, SMTP_PORT);
send(message, sserver, recipientAddress);
sserver.close();
if (listener != null) {
MailEvent event = new MailEvent(message, null);
listener.handleEvent(event);
}
}
} catch (Exception ex) {
if (listener != null) {
MailEvent event = new MailEvent(message, ex);
listener.handleEvent(event);
} else {
logger.error(null, ex);
}
}
}
private void send(MailMessage message, Socket sserver, MailAddress recipientAddress) throws IOException {
// A bit convoluted, but doesn't depend on DNS in any way...
InetAddress localhost = sserver.getLocalAddress();
String localaddress = localhost.getHostAddress();
MailAddress sender = message.getSender();
message.setCurrentRecipient(recipientAddress);
// Mandatory header fields, Date and From
if (message.getHeader("Date") == null) {
message.addHeader("Date", new java.util.Date().toString());
}
if (message.getHeader("From") == null) {
message.addHeader("From", sender.getAlias() + " <" + sender.getEmailAddress() + ">");
}
// if (message.getHeader("From") == null){
message.addHeader("To", recipientAddress.getAlias() + " <" + recipientAddress.getEmailAddress() + ">");
// }
out = new OutputStreamWriter(sserver.getOutputStream());
in = new BufferedReader(new InputStreamReader(sserver.getInputStream()));
String sintro = readln();
if (!sintro.startsWith("220")) { // 220
logger.debug("SmtpSender: intro==" + sintro);
return;
}
writeln("EHLO " + localaddress);
if (!expect250()) {
return;
}
writeln("MAIL FROM:<" + sender.getEmailAddress() + ">");
if (!expect250()) {
return;
}
writeln("RCPT TO:<" + recipientAddress.getEmailAddress() + ">");
if (!expect250()) {
return;
}
writeln("DATA");
while (true) { // may be multiple 250 replies pending from server
String line = readln();
if (line.startsWith("3"))
break; // ready to send
if (!line.startsWith("2")) {
logger.debug("SmtpSender.send reponse to DATA: " + line);
return;
}
}
for (String key : message.getHeaderFields()) {
writeln(key + ": " + message.getHeader(key));
}
writeln(""); // end of header;
for (String bline : message.getBodyLines()) {
if (bline.startsWith(".")) {
bline = "." + bline;
}
writeln(bline);
}
writeln(".");
expect250();
writeln("QUIT");
}
private boolean expect250() throws IOException {
String line = readln();
if (!line.startsWith("2")) {
logger.info("SmtpSender.expect250: " + line);
return false;
}
return true;
}
private void writeln(String s) throws IOException {
if (traceLevel > 2) {
logger.debug("From client: " + s);
}
out.write(s + "\r\n");
out.flush();
}
private String readln() throws IOException {
String line = in.readLine();
if (traceLevel > 1) {
logger.debug("From server: " + line);
}
return line;
}
/**
* Set the trace level.
*/
public void setTraceLevel(int traceLevel) {
this.traceLevel = traceLevel;
}
/**
* Return the hostname of the local machine.
*/
public String getLocalHostName() {
try {
InetAddress ipaddress = InetAddress.getLocalHost();
String localHost = ipaddress.getHostName();
if (localHost == null) {
return "localhost";
} else {
return localHost;
}
} catch (UnknownHostException e) {
return "localhost";
}
}
}
@@ -1,63 +1,63 @@
package com.avaje.ebeaninternal.server.lib.util;
import java.util.LinkedHashMap;
/**
* Utility String class that supports String manipulation functions.
*/
public class MapFromString {
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
String mapToString;
int stringLength;
int keyStart = 0;
int eqPos = 0;
int valEnd = 0;
public static LinkedHashMap<String,String> parse(String mapToString) {
MapFromString c = new MapFromString(mapToString);
return c.parse();
}
private MapFromString(String mapToString) {
if (mapToString.charAt(0) == '{'){
mapToString = mapToString.substring(1);
}
if (mapToString.charAt(mapToString.length()-1) == '}'){
mapToString = mapToString.substring(0, mapToString.length()-1);
}
this.mapToString = mapToString;
this.stringLength = mapToString.length();
}
private LinkedHashMap<String,String> parse() {
while(findNext()){
}
return map;
}
private boolean findNext() {
if (keyStart > stringLength){
return false;
}
eqPos = mapToString.indexOf("=",keyStart);
if (eqPos == -1){
throw new RuntimeException("No = after "+keyStart);
}
valEnd = mapToString.indexOf(", ",eqPos);
if (valEnd == -1){
valEnd = mapToString.length();
}
// check that the next valEnd occurs after the next eqPos
String keyValue = mapToString.substring(keyStart,eqPos);
String valValue = mapToString.substring(eqPos+1,valEnd);
map.put(keyValue, valValue);
keyStart = valEnd + 2;
return true;
}
}
package com.avaje.ebeaninternal.server.lib.util;
import java.util.LinkedHashMap;
/**
* Utility String class that supports String manipulation functions.
*/
public class MapFromString {
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
String mapToString;
int stringLength;
int keyStart = 0;
int eqPos = 0;
int valEnd = 0;
public static LinkedHashMap<String,String> parse(String mapToString) {
MapFromString c = new MapFromString(mapToString);
return c.parse();
}
private MapFromString(String mapToString) {
if (mapToString.charAt(0) == '{'){
mapToString = mapToString.substring(1);
}
if (mapToString.charAt(mapToString.length()-1) == '}'){
mapToString = mapToString.substring(0, mapToString.length()-1);
}
this.mapToString = mapToString;
this.stringLength = mapToString.length();
}
private LinkedHashMap<String,String> parse() {
while(findNext()){
}
return map;
}
private boolean findNext() {
if (keyStart > stringLength){
return false;
}
eqPos = mapToString.indexOf("=",keyStart);
if (eqPos == -1){
throw new RuntimeException("No = after "+keyStart);
}
valEnd = mapToString.indexOf(", ",eqPos);
if (valEnd == -1){
valEnd = mapToString.length();
}
// check that the next valEnd occurs after the next eqPos
String keyValue = mapToString.substring(keyStart,eqPos);
String valValue = mapToString.substring(eqPos+1,valEnd);
map.put(keyValue, valValue);
keyStart = valEnd + 2;
return true;
}
}
@@ -1,40 +1,40 @@
package com.avaje.ebeaninternal.server.lib.util;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Helper methods to determine the mime type based on a file name.
*/
public class MimeTypeHelper {
/**
* Return the mimeType for a given file path.
* This will extract the file extension, and then use that
* to look up an appropriate mime type (from the mimetypes.props file).
*
* To add a new mime type, add it to the mimetype.props file.
*/
public static String getMimeType(String filePath) {
int lastPeriod = filePath.lastIndexOf(".");
if (lastPeriod > -1) {
filePath = filePath.substring(lastPeriod+1);
}
try {
return resources.getString(filePath.toLowerCase());
} catch (MissingResourceException e) {
return null;
//String m = "Unable to locate mimetype for ["+filePath.toLowerCase()+"] in mimetypes.properties";
//throw new NotFoundException(m);
}
}
private static ResourceBundle resources = ResourceBundle.getBundle("com.avaje.lib.util.mimetypes");
};
package com.avaje.ebeaninternal.server.lib.util;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Helper methods to determine the mime type based on a file name.
*/
public class MimeTypeHelper {
/**
* Return the mimeType for a given file path.
* This will extract the file extension, and then use that
* to look up an appropriate mime type (from the mimetypes.props file).
*
* To add a new mime type, add it to the mimetype.props file.
*/
public static String getMimeType(String filePath) {
int lastPeriod = filePath.lastIndexOf(".");
if (lastPeriod > -1) {
filePath = filePath.substring(lastPeriod+1);
}
try {
return resources.getString(filePath.toLowerCase());
} catch (MissingResourceException e) {
return null;
//String m = "Unable to locate mimetype for ["+filePath.toLowerCase()+"] in mimetypes.properties";
//throw new NotFoundException(m);
}
}
private static ResourceBundle resources = ResourceBundle.getBundle("com.avaje.lib.util.mimetypes");
};
@@ -1,23 +1,23 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception where data is not found.
*/
public class NotFoundException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539845L;
public NotFoundException(Exception cause) {
super(cause);
}
public NotFoundException(String s, Exception cause) {
super(s, cause);
}
public NotFoundException(String s) {
super(s);
}
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general exception where data is not found.
*/
public class NotFoundException extends RuntimeException
{
static final long serialVersionUID = 7061559938704539845L;
public NotFoundException(Exception cause) {
super(cause);
}
public NotFoundException(String s, Exception cause) {
super(s, cause);
}
public NotFoundException(String s) {
super(s);
}
}
File diff suppressed because it is too large Load Diff
@@ -1,15 +1,15 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general string parsing exception.
*/
public class StringParsingException extends RuntimeException {
static final long serialVersionUID = -3070423471260426402L;
public StringParsingException(String message) {
super(message);
}
};
package com.avaje.ebeaninternal.server.lib.util;
/**
* A general string parsing exception.
*/
public class StringParsingException extends RuntimeException {
static final long serialVersionUID = -3070423471260426402L;
public StringParsingException(String message) {
super(message);
}
};
@@ -1,91 +1,91 @@
package com.avaje.ebeaninternal.server.lib.util;
/**
* Builds a string from a stack trace.
* <p>
* Generally used to flatten a stack trace into a single string
* removing \r\n and limiting the size of any given stack.
* </p>
*/
public class ThrowablePrinter {
private static final String atString = " at ";
private String newLineChar = "\\r\\n";
private int maxStackTraceLines = 3;
/**
* Set the maximum number of lines in any one part of
* the stack trace. This is not the total maximum.
*/
public void setMaxStackTraceLines(int maxStackTraceLines) {
this.maxStackTraceLines = maxStackTraceLines;
}
/**
* Set the new line character used to replace \r\n with.
* This is useful so that the stack is placed on a single line
* in a log file.
*/
public void setNewLineChar(String newLineChar) {
this.newLineChar = newLineChar;
}
/**
* Convert the error into a string representation.
* <p>
* Replaces the \r\n and limits the stack lines.
* </p>
*/
public String print(Throwable e) {
StringBuffer sb = new StringBuffer();
printThrowable(sb, e, false);
String line = sb.toString();
line = StringHelper.replaceString(line, "\r", "\\r");
line = StringHelper.replaceString(line, "\n", "\\n");
return line;
}
/**
* Recursively output the Throwable stack trace to the log.
*
* @param sb the buffer to write the stack trace to
* @param e the source throwable
* @param isCause flag to indicate if this is the top level throwable or a
* cause
*/
protected void printThrowable(StringBuffer sb, Throwable e, boolean isCause) {
if (e != null) {
if (isCause) {
sb.append("Caused by: ");
}
sb.append(e.getClass().getName());
sb.append(":");
sb.append(e.getMessage()).append(newLineChar);
StackTraceElement[] ste = e.getStackTrace();
int outputStackLines = ste.length;
int notShownCount = 0;
if (ste.length > maxStackTraceLines) {
outputStackLines = maxStackTraceLines;
notShownCount = ste.length - outputStackLines;
}
for (int i = 0; i < outputStackLines; i++) {
sb.append(atString);
sb.append(ste[i].toString()).append(newLineChar);
}
if (notShownCount > 0) {
sb.append(" ... ");
sb.append(notShownCount);
sb.append(" more").append(newLineChar);
}
Throwable cause = e.getCause();
if (cause != null) {
printThrowable(sb, cause, true);
}
}
}
}
package com.avaje.ebeaninternal.server.lib.util;
/**
* Builds a string from a stack trace.
* <p>
* Generally used to flatten a stack trace into a single string
* removing \r\n and limiting the size of any given stack.
* </p>
*/
public class ThrowablePrinter {
private static final String atString = " at ";
private String newLineChar = "\\r\\n";
private int maxStackTraceLines = 3;
/**
* Set the maximum number of lines in any one part of
* the stack trace. This is not the total maximum.
*/
public void setMaxStackTraceLines(int maxStackTraceLines) {
this.maxStackTraceLines = maxStackTraceLines;
}
/**
* Set the new line character used to replace \r\n with.
* This is useful so that the stack is placed on a single line
* in a log file.
*/
public void setNewLineChar(String newLineChar) {
this.newLineChar = newLineChar;
}
/**
* Convert the error into a string representation.
* <p>
* Replaces the \r\n and limits the stack lines.
* </p>
*/
public String print(Throwable e) {
StringBuffer sb = new StringBuffer();
printThrowable(sb, e, false);
String line = sb.toString();
line = StringHelper.replaceString(line, "\r", "\\r");
line = StringHelper.replaceString(line, "\n", "\\n");
return line;
}
/**
* Recursively output the Throwable stack trace to the log.
*
* @param sb the buffer to write the stack trace to
* @param e the source throwable
* @param isCause flag to indicate if this is the top level throwable or a
* cause
*/
protected void printThrowable(StringBuffer sb, Throwable e, boolean isCause) {
if (e != null) {
if (isCause) {
sb.append("Caused by: ");
}
sb.append(e.getClass().getName());
sb.append(":");
sb.append(e.getMessage()).append(newLineChar);
StackTraceElement[] ste = e.getStackTrace();
int outputStackLines = ste.length;
int notShownCount = 0;
if (ste.length > maxStackTraceLines) {
outputStackLines = maxStackTraceLines;
notShownCount = ste.length - outputStackLines;
}
for (int i = 0; i < outputStackLines; i++) {
sb.append(atString);
sb.append(ste[i].toString()).append(newLineChar);
}
if (notShownCount > 0) {
sb.append(" ... ");
sb.append(notShownCount);
sb.append(" more").append(newLineChar);
}
Throwable cause = e.getCause();
if (cause != null) {
printThrowable(sb, cause, true);
}
}
}
}