├── .sonarcloud.properties ├── README ├── atmosphere-per-session-broadcaster ├── atmosphere-per-session-broadcaster.iml ├── pom.xml └── src │ └── main │ ├── java │ └── net │ │ └── javaforge │ │ └── blog │ │ └── atmosphere │ │ ├── BroadcasterCreater.java │ │ └── UserSessionAwareAtmosphereHandler.java │ └── webapp │ ├── WEB-INF │ └── web.xml │ ├── index.jsp │ └── js │ ├── jquery-1.7.2.js │ └── jquery.atmosphere.js ├── camel-rnd ├── README.md ├── ReadMe.txt ├── camel-rnd.iml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── javaforge │ │ │ └── blog │ │ │ └── camel │ │ │ └── rnd │ │ │ ├── RndComponent.java │ │ │ ├── RndConsumer.java │ │ │ ├── RndEndpoint.java │ │ │ └── RndGenerator.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── org │ │ └── apache │ │ └── camel │ │ └── component │ │ └── rnd │ └── test │ ├── java │ └── net │ │ └── javaforge │ │ └── blog │ │ └── camel │ │ └── rnd │ │ └── test │ │ ├── RndFileTest.java │ │ ├── RndSimpleTest.java │ │ └── RndWithAggregatorTest.java │ └── resources │ └── log4j.xml ├── dbconf ├── conf │ ├── jetty-config.xml │ ├── jetty-env.xml │ └── webdefault.xml ├── dbconf.h2.db ├── dbconf.iml ├── dbconf.trace.db ├── pom.xml ├── readme.txt └── src │ └── main │ ├── java │ └── net │ │ └── javaforge │ │ └── blog │ │ └── dbconf │ │ ├── ApplicationProperties.java │ │ ├── ApplicationPropertiesInitializer.java │ │ ├── DatabaseAwareApplicationPropertiesInitializer.java │ │ ├── LogbackInitializer.java │ │ └── beans │ │ └── AppInfoBean.java │ ├── resources │ └── META-INF │ │ └── applicationContext.xml │ └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.jsp ├── docbkx ├── conf │ └── customization-fopdf.xsl ├── docbkx.iml ├── docs │ ├── bibliography.inc.xml │ ├── images │ │ ├── draft.png │ │ └── logo.png │ ├── manual.xml │ ├── section0.inc.xml │ ├── section1.inc.xml │ ├── section2.inc.xml │ ├── section3.inc.xml │ └── section4.inc.xml ├── manual.pdf ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── javaforge │ └── blog │ └── docbkx │ └── App.java ├── liquibase-sample ├── db │ ├── ddl │ │ ├── 1.x │ │ │ ├── 1.0 │ │ │ │ └── db.changelog-1.0.xml │ │ │ ├── 1.1 │ │ │ │ └── db.changelog-1.1.xml │ │ │ ├── 1.2 │ │ │ │ └── db.changelog-1.2.xml │ │ │ └── db.changelog-1.x.xml │ │ └── db.changelog-master.xml │ ├── liquibase.properties │ └── testdata │ │ ├── addresses.csv │ │ ├── db.testdata.xml │ │ ├── roles.csv │ │ └── users.csv ├── liquibase-sample.iml ├── pom.xml ├── readme.txt └── src │ └── test │ └── java │ └── net │ └── javaforge │ └── blog │ └── liquibase │ └── TestWithLiquibase.java ├── restgwt-groovy ├── GenerateRestAsyncResources.groovy ├── pom.xml ├── restgwt-groovy.iml └── src │ └── main │ ├── java │ └── net │ │ └── javaforge │ │ └── gwt │ │ └── rest │ │ ├── client │ │ └── App.java │ │ ├── server │ │ └── remote │ │ │ └── rest │ │ │ └── PersonResource.java │ │ └── shared │ │ └── domain │ │ └── Person.java │ ├── resources │ └── net │ │ └── javaforge │ │ └── gwt │ │ └── rest │ │ └── App.gwt.xml │ └── webapp │ ├── App.css │ ├── App.html │ └── WEB-INF │ └── web.xml ├── restgwt ├── pom.xml ├── restgwt.iml └── src │ └── main │ ├── java │ └── net │ │ └── javaforge │ │ └── gwt │ │ └── rest │ │ ├── client │ │ ├── App.java │ │ └── remote │ │ │ └── rest │ │ │ └── PersonResourceAsync.java │ │ ├── server │ │ └── remote │ │ │ └── rest │ │ │ └── PersonResource.java │ │ └── shared │ │ └── domain │ │ └── Person.java │ ├── resources │ └── net │ │ └── javaforge │ │ └── gwt │ │ └── rest │ │ └── App.gwt.xml │ └── webapp │ ├── App.css │ ├── App.html │ └── WEB-INF │ └── web.xml ├── springaop-custom-interceptor ├── pom.xml ├── springaop-custom-interceptor.iml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── javaforge │ │ │ └── blog │ │ │ └── spring │ │ │ ├── Bean.java │ │ │ └── aop │ │ │ ├── ProfileExecution.java │ │ │ ├── ProfilingAdvisor.java │ │ │ └── ProfilingMethodInterceptor.java │ └── resources │ │ └── applicationContext.xml │ └── test │ └── java │ └── net │ └── javaforge │ └── blog │ └── spring │ └── ProfilingTest.java └── sshd-daemon-demo ├── pom.xml ├── src └── main │ └── java │ └── net │ └── javaforge │ └── blog │ └── sshd │ ├── App.java │ ├── InAppPasswordAuthenticator.java │ └── InAppShellFactory.java └── sshd-daemon-demo.iml /.sonarcloud.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Source code examples for my blog: http://blog.javaforge.net 2 | 3 | 4 | This file was created by IntelliJ IDEA 11.1.3 for binding GitHub repository 5 | -------------------------------------------------------------------------------- /atmosphere-per-session-broadcaster/atmosphere-per-session-broadcaster.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 61 | 219 | 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /atmosphere-per-session-broadcaster/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | net.javaforge.blog 5 | atmosphere-per-session-broadcaster 6 | war 7 | 0.0.1-SNAPSHOT 8 | atmosphere-per-session-broadcaster example 9 | http://maven.apache.org 10 | 11 | 12 | 13 | 14 | javax.servlet 15 | servlet-api 16 | 2.5 17 | provided 18 | 19 | 20 | org.atmosphere 21 | atmosphere-runtime 22 | 1.0.0 23 | 24 | 25 | org.slf4j 26 | slf4j-api 27 | 1.6.6 28 | 29 | 30 | org.slf4j 31 | slf4j-simple 32 | 1.6.6 33 | 34 | 35 | junit 36 | junit 37 | 3.8.1 38 | test 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-compiler-plugin 49 | 2.5.1 50 | 51 | 1.6 52 | 1.6 53 | true 54 | UTF-8 55 | true 56 | true 57 | true 58 | 59 | 60 | 61 | 62 | org.mortbay.jetty 63 | maven-jetty-plugin 64 | 6.1.26 65 | 66 | 0 67 | 68 | 69 | 70 | 71 | 72 | atmosphere-per-session-broadcaster 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /atmosphere-per-session-broadcaster/src/main/java/net/javaforge/blog/atmosphere/BroadcasterCreater.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.atmosphere; 2 | 3 | import javax.servlet.http.HttpSession; 4 | import javax.servlet.http.HttpSessionEvent; 5 | import javax.servlet.http.HttpSessionListener; 6 | 7 | import org.atmosphere.cpr.BroadcasterFactory; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | public class BroadcasterCreater implements HttpSessionListener { 12 | 13 | private static final Logger LOG = LoggerFactory 14 | .getLogger(BroadcasterCreater.class); 15 | 16 | public static final String BROADCASTER_ID_KEY = "net.javaforge.blog.atmosphere.broadcasterId"; 17 | 18 | @Override 19 | public void sessionCreated(HttpSessionEvent se) { 20 | HttpSession session = se.getSession(); 21 | String broadcasterId = "/broadcaster/" + session.getId(); 22 | 23 | LOG.info("Creating broadcaster: {}", broadcasterId); 24 | BroadcasterFactory.getDefault().lookup(broadcasterId, true); 25 | session.setAttribute(BROADCASTER_ID_KEY, broadcasterId); 26 | } 27 | 28 | @Override 29 | public void sessionDestroyed(HttpSessionEvent se) { 30 | HttpSession session = se.getSession(); 31 | String broadcasterId = (String) session 32 | .getAttribute(BROADCASTER_ID_KEY); 33 | 34 | LOG.info("Removing broadcaster: {}", broadcasterId); 35 | BroadcasterFactory.getDefault().remove(broadcasterId); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /atmosphere-per-session-broadcaster/src/main/java/net/javaforge/blog/atmosphere/UserSessionAwareAtmosphereHandler.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.atmosphere; 2 | 3 | import java.io.IOException; 4 | 5 | import org.atmosphere.config.service.AtmosphereHandlerService; 6 | import org.atmosphere.cpr.ApplicationConfig; 7 | import org.atmosphere.cpr.AtmosphereRequest; 8 | import org.atmosphere.cpr.AtmosphereResource; 9 | import org.atmosphere.cpr.AtmosphereResponse; 10 | import org.atmosphere.cpr.Broadcaster; 11 | import org.atmosphere.cpr.BroadcasterFactory; 12 | import org.atmosphere.cpr.HeaderConfig; 13 | import org.atmosphere.cpr.MetaBroadcaster; 14 | import org.atmosphere.handler.AbstractReflectorAtmosphereHandler; 15 | import org.atmosphere.websocket.WebSocketEventListenerAdapter; 16 | import org.slf4j.Logger; 17 | import org.slf4j.LoggerFactory; 18 | 19 | @AtmosphereHandlerService 20 | public class UserSessionAwareAtmosphereHandler extends 21 | AbstractReflectorAtmosphereHandler { 22 | 23 | private static final Logger LOG = LoggerFactory 24 | .getLogger(UserSessionAwareAtmosphereHandler.class); 25 | 26 | @Override 27 | public void onRequest(AtmosphereResource resource) throws IOException { 28 | 29 | suspendAtmosphereResourceIfNecessary(resource); 30 | 31 | if ("POST".equalsIgnoreCase(resource.getRequest().getMethod())) { 32 | doBroadcast(resource); 33 | } 34 | 35 | } 36 | 37 | private void doBroadcast(AtmosphereResource resource) throws IOException { 38 | 39 | AtmosphereRequest req = resource.getRequest(); 40 | 41 | String incomingMessage = req.getReader().readLine(); 42 | LOG.info("Incoming message: '{}'", incomingMessage); 43 | 44 | Broadcaster broadcaster = null; 45 | if (incomingMessage.startsWith("@/broadcaster/")) { 46 | String broadcasterId = incomingMessage.substring(1, 47 | incomingMessage.indexOf(" ")); 48 | broadcaster = lookupBroadcaster(broadcasterId); 49 | } else { 50 | broadcaster = lookupBroadcaster(req); 51 | } 52 | 53 | LOG.info("Broadcasting message with broadcaster = {}", 54 | broadcaster.getID()); 55 | broadcaster.broadcast("ACK! Sent message was: " 56 | + incomingMessage + ""); 57 | 58 | } 59 | 60 | private void suspendAtmosphereResourceIfNecessary( 61 | AtmosphereResource resource) { 62 | 63 | AtmosphereRequest req = resource.getRequest(); 64 | AtmosphereResponse resp = resource.getResponse(); 65 | String method = req.getMethod(); 66 | 67 | if ("GET".equalsIgnoreCase(method)) { 68 | 69 | LOG.info("GET request detected, suspending broadcaster..."); 70 | 71 | // Log all events on the console, including WebSocket events. 72 | resource.addEventListener(new WebSocketEventListenerAdapter()); 73 | 74 | resp.setContentType("text/html;charset=ISO-8859-1"); 75 | 76 | Broadcaster b = lookupBroadcaster(req); 77 | resource.setBroadcaster(b); 78 | 79 | if (req.getHeader(HeaderConfig.X_ATMOSPHERE_TRANSPORT) 80 | .equalsIgnoreCase(HeaderConfig.LONG_POLLING_TRANSPORT)) { 81 | req.setAttribute(ApplicationConfig.RESUME_ON_BROADCAST, 82 | Boolean.TRUE); 83 | resource.suspend(-1, false); 84 | } else { 85 | resource.suspend(-1); 86 | } 87 | 88 | LOG.info("Broadcasting notification message to all connected users..."); 89 | MetaBroadcaster.getDefault().broadcastTo( 90 | "/broadcaster/*", 91 | "new broadcaster connected: " + b.getID() 92 | + ""); 93 | } 94 | 95 | } 96 | 97 | @Override 98 | public void destroy() { 99 | 100 | } 101 | 102 | private Broadcaster lookupBroadcaster(AtmosphereRequest req) { 103 | String broadcasterId = (String) req.getSession().getAttribute( 104 | BroadcasterCreater.BROADCASTER_ID_KEY); 105 | return lookupBroadcaster(broadcasterId); 106 | } 107 | 108 | private Broadcaster lookupBroadcaster(String broadcasterId) { 109 | LOG.info("Looking up for broadcaster: {}", broadcasterId); 110 | Broadcaster broadcaster = BroadcasterFactory.getDefault().lookup( 111 | broadcasterId); 112 | 113 | LOG.info("Broadcaster found : {}", broadcaster.getID()); 114 | return broadcaster; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /atmosphere-per-session-broadcaster/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | net.javaforge.blog.atmosphere.BroadcasterCreater 9 | 10 | 11 | 12 | 13 | AtmosphereServlet 14 | AtmosphereServlet 15 | org.atmosphere.cpr.AtmosphereServlet 16 | 17 | org.atmosphere.cpr.AtmosphereHandler 18 | net.javaforge.blog.atmosphere.UserSessionAwareAtmosphereHandler 19 | 20 | 21 | 22 | org.atmosphere.useNative 23 | true 24 | 25 | 26 | org.atmosphere.cpr.sessionSupport 27 | true 28 | 29 | 0 30 | 31 | 32 | 33 | AtmosphereServlet 34 | /atmosphere/* 35 | 36 | 37 | 38 | 39 | index.jsp 40 | 41 | 42 | 53 | -------------------------------------------------------------------------------- /atmosphere-per-session-broadcaster/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <% 2 | String broadcasterId = (String) session 3 | .getAttribute("net.javaforge.blog.atmosphere.broadcasterId"); 4 | %> 5 | 6 | 7 | 8 | 9 | 107 | 116 | 117 | 118 |
119 | Broadcaster associated with the user session: <%=broadcasterId%> 120 |
121 |

Select transport to use for subscribing

122 |

You can change the transport any time.

123 |
124 | 132 |
133 |
134 | 135 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /camel-rnd/README.md: -------------------------------------------------------------------------------- 1 | This project demonstrates how to create a simple Apache Camel component. 2 | It generates random character sequences that can be consumed by the subsequent route nodes. 3 | 4 | Component's URI format: 5 | 6 | ``` 7 | rnd:someName[?options] 8 | ``` 9 | 10 | Options: 11 | 12 | | Name | Default Value | Description 13 | --- | --- | --- 14 | generator | random | possible values: random, alphabetic, alphanumeric, numeric, ascii 15 | length | 10 | length of the generated character sequence 16 | chars | | characters to use for generation. available only for generator == random 17 | letters | false | use letters for generations. available only for generator == random 18 | numbers | false | use numbers for generations. available only for generator == random 19 | start | 0 | the position in set of chars to start at. available only for generator == random 20 | end | 0 | the position in set of chars to end before. available only for generator == random 21 | 22 | 23 | Usage examples: 24 | 25 | Repeatedly generate random alphabetic character sequences each 5 characters long 26 | and send them to the console output stream. 27 | 28 | ```java 29 | from("rnd:foo?generator=alphabetic&length=30").to("stream:out"); 30 | ``` 31 | 32 | Repeatedly generate random alphanumeric character sequences each 100 characters long, 33 | aggregate them to the lists of 5 elements and send each list as a new message to the subsequent log component. 34 | 35 | ```java 36 | from("rnd:foo?generator=alphanumeric&initialDelay=0&delay=50&length=100") 37 | .setHeader("foo", constant("bar")) 38 | .aggregate(header("foo"), new ListAggregationStrategy()) 39 | .completionSize(5) 40 | .to("log:net.javaforge.blog.camel?level=INFO"); 41 | 42 | 43 | private static class ListAggregationStrategy implements AggregationStrategy { 44 | 45 | @SuppressWarnings("unchecked") 46 | @Override 47 | public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { 48 | Object newBody = newExchange.getIn().getBody(); 49 | List list; 50 | if (oldExchange == null) { 51 | list = new ArrayList(); 52 | list.add(newBody); 53 | newExchange.getIn().setBody(list); 54 | return newExchange; 55 | } else { 56 | list = oldExchange.getIn().getBody(List.class); 57 | list.add(newBody); 58 | return oldExchange; 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | Repeatedly generate random alphanumeric character sequences each 50 characters long and 65 | append them to the existing file out.txt 66 | 67 | ```java 68 | from("rnd:foo?generator=alphanumeric&delay=10&length=50") 69 | .process(new Processor() { 70 | @Override 71 | public void process(Exchange exchange) throws Exception { 72 | exchange.getIn().setBody(exchange.getIn().getBody() + "\n"); 73 | } 74 | }) 75 | .to("file:target?fileName=out.txt&fileExist=Append") 76 | ``` 77 | -------------------------------------------------------------------------------- /camel-rnd/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Camel Component Project 2 | ======================= 3 | 4 | This project is a example of a simple Camel component. 5 | 6 | To build this project use 7 | 8 | mvn install 9 | 10 | For more help see the Apache Camel documentation: 11 | 12 | http://camel.apache.org/writing-components.html 13 | 14 | 15 | Creating new camel component project using maven archetype 16 | -------------------------------------- 17 | 18 | mvn archetype:generate \ 19 | -DarchetypeGroupId=org.apache.camel.archetypes \ 20 | -DarchetypeArtifactId=camel-archetype-component \ 21 | -DarchetypeVersion=2.12.1 \ 22 | -DgroupId=net.javaforge.blog.camel \ 23 | -DartifactId=camel-rnd \ 24 | -Dname=Rnd \ 25 | -Dscheme=rnd -------------------------------------------------------------------------------- /camel-rnd/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | net.javaforge.blog.camel 8 | camel-rnd 9 | bundle 10 | 1.0.0-SNAPSHOT 11 | 12 | Camel Rnd Component 13 | http://blog.javaforge.net 14 | 15 | 16 | UTF-8 17 | UTF-8 18 | 19 | 20 | 21 | 22 | org.apache.camel 23 | camel-core 24 | 2.24.0 25 | 26 | 27 | org.apache.commons 28 | commons-lang3 29 | 3.1 30 | 31 | 32 | 33 | 34 | org.slf4j 35 | slf4j-api 36 | 1.7.5 37 | 38 | 39 | org.slf4j 40 | slf4j-log4j12 41 | 1.7.5 42 | test 43 | 44 | 45 | log4j 46 | log4j 47 | 1.2.17 48 | test 49 | 50 | 51 | 52 | 53 | org.apache.camel 54 | camel-test 55 | 2.12.1 56 | test 57 | 58 | 59 | 60 | 61 | install 62 | 63 | 64 | 65 | 66 | org.apache.maven.plugins 67 | maven-compiler-plugin 68 | 2.5.1 69 | 70 | 1.6 71 | 1.6 72 | 73 | 74 | 75 | 76 | org.apache.maven.plugins 77 | maven-resources-plugin 78 | 2.6 79 | 80 | UTF-8 81 | 82 | 83 | 84 | 85 | 86 | org.apache.maven.plugins 87 | maven-eclipse-plugin 88 | 2.9 89 | 90 | true 91 | true 92 | 93 | 94 | 95 | 96 | 97 | org.apache.felix 98 | maven-bundle-plugin 99 | 2.3.7 100 | true 101 | 102 | 103 | net.javaforge.blog.camel-rnd 104 | org.apache.camel.spi.ComponentResolver;component=rnd 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /camel-rnd/src/main/java/net/javaforge/blog/camel/rnd/RndComponent.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.camel.rnd; 2 | 3 | import org.apache.camel.Endpoint; 4 | import org.apache.camel.impl.DefaultComponent; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * Represents the component that manages {@link RndEndpoint}. 10 | */ 11 | public class RndComponent extends DefaultComponent { 12 | 13 | protected Endpoint createEndpoint(String uri, String remaining, 14 | Map parameters) throws Exception { 15 | Endpoint endpoint = new RndEndpoint(uri, this); 16 | 17 | // convert "generator" parameter to uppercase if exists 18 | String generator = (String) parameters.get("generator"); 19 | if (generator != null) 20 | parameters.put("generator", generator.toUpperCase()); 21 | 22 | setProperties(endpoint, parameters); 23 | return endpoint; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /camel-rnd/src/main/java/net/javaforge/blog/camel/rnd/RndConsumer.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.camel.rnd; 2 | 3 | import org.apache.camel.Exchange; 4 | import org.apache.camel.Processor; 5 | import org.apache.camel.impl.ScheduledPollConsumer; 6 | import org.apache.camel.util.ObjectHelper; 7 | 8 | /** 9 | * The Rnd consumer. 10 | */ 11 | public class RndConsumer extends ScheduledPollConsumer { 12 | 13 | private final RndEndpoint endpoint; 14 | 15 | public RndConsumer(RndEndpoint endpoint, Processor processor) { 16 | super(endpoint, processor); 17 | this.endpoint = endpoint; 18 | } 19 | 20 | @Override 21 | protected int poll() throws Exception { 22 | 23 | Exchange exchange = endpoint.createExchange(); 24 | 25 | // create a message body 26 | exchange.getIn().setBody(generateRandomSequence()); 27 | 28 | try { 29 | // send message to next processor in the route 30 | getProcessor().process(exchange); 31 | return 1; // number of messages polled 32 | } finally { 33 | // log exception if an exception occurred and was not handled 34 | if (exchange.getException() != null) { 35 | getExceptionHandler().handleException( 36 | "Error processing exchange", exchange, 37 | exchange.getException()); 38 | } 39 | } 40 | } 41 | 42 | private String generateRandomSequence() { 43 | RndGenerator generator = endpoint.getGenerator(); 44 | ObjectHelper.notNull(generator, "generator"); 45 | return generator.length(endpoint.getLength()) 46 | .chars(endpoint.getChars()).letters(endpoint.isLetters()) 47 | .numbers(endpoint.isNumbers()).start(endpoint.getStart()).end( 48 | endpoint.getEnd()).generate(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /camel-rnd/src/main/java/net/javaforge/blog/camel/rnd/RndEndpoint.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.camel.rnd; 2 | 3 | import org.apache.camel.Consumer; 4 | import org.apache.camel.Processor; 5 | import org.apache.camel.Producer; 6 | import org.apache.camel.RuntimeCamelException; 7 | import org.apache.camel.impl.DefaultPollingEndpoint; 8 | import org.apache.camel.spi.UriEndpoint; 9 | import org.apache.camel.spi.UriParam; 10 | 11 | /** 12 | * Represents a Rnd endpoint. 13 | */ 14 | @UriEndpoint(scheme = "rnd") 15 | public class RndEndpoint extends DefaultPollingEndpoint { 16 | 17 | @UriParam 18 | private RndGenerator generator = RndGenerator.RANDOM; 19 | 20 | @UriParam 21 | private int length = 10; 22 | 23 | @UriParam 24 | private String chars = null; 25 | 26 | @UriParam 27 | private boolean letters = false; 28 | 29 | @UriParam 30 | private boolean numbers = false; 31 | 32 | @UriParam 33 | private int start = 0; 34 | 35 | @UriParam 36 | private int end = 0; 37 | 38 | public RndEndpoint() { 39 | } 40 | 41 | public RndEndpoint(String uri, RndComponent component) { 42 | super(uri, component); 43 | } 44 | 45 | public Producer createProducer() throws Exception { 46 | throw new RuntimeCamelException("Cannot produce to a RndEndpoint: " 47 | + getEndpointUri()); 48 | } 49 | 50 | public Consumer createConsumer(Processor processor) throws Exception { 51 | RndConsumer consumer = new RndConsumer(this, processor); 52 | configureConsumer(consumer); 53 | return consumer; 54 | } 55 | 56 | public boolean isSingleton() { 57 | return true; 58 | } 59 | 60 | public int getLength() { 61 | return length; 62 | } 63 | 64 | public void setLength(int length) { 65 | this.length = length; 66 | } 67 | 68 | public RndGenerator getGenerator() { 69 | return generator; 70 | } 71 | 72 | public void setGenerator(RndGenerator generator) { 73 | this.generator = generator; 74 | } 75 | 76 | public String getChars() { 77 | return chars; 78 | } 79 | 80 | public void setChars(String chars) { 81 | this.chars = chars; 82 | } 83 | 84 | public boolean isLetters() { 85 | return letters; 86 | } 87 | 88 | public void setLetters(boolean letters) { 89 | this.letters = letters; 90 | } 91 | 92 | public boolean isNumbers() { 93 | return numbers; 94 | } 95 | 96 | public void setNumbers(boolean numbers) { 97 | this.numbers = numbers; 98 | } 99 | 100 | public int getStart() { 101 | return start; 102 | } 103 | 104 | public void setStart(int start) { 105 | this.start = start; 106 | } 107 | 108 | public int getEnd() { 109 | return end; 110 | } 111 | 112 | public void setEnd(int end) { 113 | this.end = end; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /camel-rnd/src/main/java/net/javaforge/blog/camel/rnd/RndGenerator.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.camel.rnd; 2 | 3 | import org.apache.commons.lang3.RandomStringUtils; 4 | 5 | /** 6 | * Generates random string sequence. 7 | */ 8 | public enum RndGenerator { 9 | 10 | RANDOM { 11 | @Override 12 | public String generate() { 13 | if (chars != null) 14 | return RandomStringUtils.random(length, chars); 15 | else 16 | return RandomStringUtils.random(length, start, end, letters, 17 | numbers); 18 | } 19 | }, 20 | ALPHABETIC { 21 | @Override 22 | public String generate() { 23 | return RandomStringUtils.randomAlphabetic(length); 24 | } 25 | }, 26 | ALPHANUMERIC { 27 | @Override 28 | public String generate() { 29 | return RandomStringUtils.randomAlphanumeric(length); 30 | } 31 | }, 32 | NUMERIC { 33 | @Override 34 | public String generate() { 35 | return RandomStringUtils.randomNumeric(length); 36 | } 37 | }, 38 | ASCII { 39 | @Override 40 | public String generate() { 41 | return RandomStringUtils.randomAscii(length); 42 | } 43 | }; 44 | 45 | int length; 46 | 47 | String chars; 48 | 49 | boolean letters = false; 50 | 51 | boolean numbers = false; 52 | 53 | int start = 0; 54 | 55 | int end = 0; 56 | 57 | private RndGenerator() { 58 | this(10); 59 | } 60 | 61 | private RndGenerator(int length) { 62 | this.length = length; 63 | } 64 | 65 | public RndGenerator chars(String chars) { 66 | this.chars = chars; 67 | return this; 68 | } 69 | 70 | public RndGenerator letters(boolean letters) { 71 | this.letters = letters; 72 | return this; 73 | } 74 | 75 | public RndGenerator numbers(boolean numbers) { 76 | this.numbers = numbers; 77 | return this; 78 | } 79 | 80 | public RndGenerator length(int length) { 81 | this.length = length; 82 | return this; 83 | } 84 | 85 | public RndGenerator start(int start) { 86 | this.start = start; 87 | return this; 88 | } 89 | 90 | public RndGenerator end(int end) { 91 | this.end = end; 92 | return this; 93 | } 94 | 95 | /** 96 | * Generates random string sequence... 97 | * 98 | * @return random string 99 | */ 100 | public abstract String generate(); 101 | 102 | } 103 | -------------------------------------------------------------------------------- /camel-rnd/src/main/resources/META-INF/services/org/apache/camel/component/rnd: -------------------------------------------------------------------------------- 1 | class=net.javaforge.blog.camel.rnd.RndComponent 2 | -------------------------------------------------------------------------------- /camel-rnd/src/test/java/net/javaforge/blog/camel/rnd/test/RndFileTest.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.camel.rnd.test; 2 | 3 | import org.apache.camel.Exchange; 4 | import org.apache.camel.Processor; 5 | import org.apache.camel.builder.RouteBuilder; 6 | import org.apache.camel.component.mock.MockEndpoint; 7 | import org.apache.camel.test.junit4.CamelTestSupport; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | 11 | import java.io.File; 12 | import java.util.Scanner; 13 | 14 | /** 15 | * 16 | */ 17 | public class RndFileTest extends CamelTestSupport { 18 | 19 | private static final int expectedMessageCount = 20; 20 | 21 | private static final int expectedMessageLength = 50; 22 | 23 | private static final String expectedFilename = "target/out.txt"; 24 | 25 | @Before 26 | public void setupTest() { 27 | File f = new File(expectedFilename); 28 | if (f.exists()) 29 | f.delete(); 30 | } 31 | 32 | @Test 33 | public void testWriteToFile() throws Exception { 34 | 35 | MockEndpoint mockOut = getMockEndpoint("mock:out"); 36 | mockOut.expectedMinimumMessageCount(expectedMessageCount); 37 | 38 | assertMockEndpointsSatisfied(); 39 | 40 | assertFileExists(expectedFilename); 41 | 42 | Scanner scanner = new Scanner(new File(expectedFilename)); 43 | int counter = 0; 44 | while (scanner.hasNext()) { 45 | String line = scanner.nextLine(); 46 | assertNotNull(line); 47 | assertEquals(expectedMessageLength, line.length()); 48 | counter++; 49 | } 50 | assertEquals(expectedMessageCount, counter); 51 | } 52 | 53 | @Override 54 | protected RouteBuilder createRouteBuilder() throws Exception { 55 | return new RouteBuilder() { 56 | 57 | @Override 58 | public void configure() throws Exception { 59 | from( 60 | "rnd:foo?generator=alphanumeric&delay=10&length=" 61 | + expectedMessageLength).process( 62 | new Processor() { 63 | 64 | @Override 65 | public void process(Exchange exchange) 66 | throws Exception { 67 | exchange.getIn().setBody( 68 | exchange.getIn().getBody() + "\n"); 69 | } 70 | }).to("file:target?fileName=out.txt&fileExist=Append") 71 | .to("mock:out"); 72 | } 73 | 74 | }; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /camel-rnd/src/test/java/net/javaforge/blog/camel/rnd/test/RndSimpleTest.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.camel.rnd.test; 2 | 3 | import org.apache.camel.builder.AdviceWithRouteBuilder; 4 | import org.apache.camel.builder.RouteBuilder; 5 | import org.apache.camel.component.mock.MockEndpoint; 6 | import org.apache.camel.test.junit4.CamelTestSupport; 7 | import org.junit.Test; 8 | 9 | public class RndSimpleTest extends CamelTestSupport { 10 | 11 | private static final int expectedMessageCount = 3; 12 | 13 | private static final int expectedMessageLength = 5; 14 | 15 | @Test 16 | public void testRandomChars() throws Exception { 17 | testWithUriAndRegex( 18 | "rnd:foo?initialDelay=0&generator=random&chars=abc&length=" 19 | + expectedMessageLength, "[abc]{" 20 | + expectedMessageLength + "}"); 21 | } 22 | 23 | @Test 24 | public void testNumeric() throws Exception { 25 | testWithUriAndRegex("rnd:foo?initialDelay=0&generator=numeric&length=" 26 | + expectedMessageLength, "\\p{Digit}{" + expectedMessageLength 27 | + "}"); 28 | } 29 | 30 | @Test 31 | public void testAlphanumeric() throws Exception { 32 | testWithUriAndRegex( 33 | "rnd:foo?initialDelay=0&generator=alphanumeric&length=" 34 | + expectedMessageLength, "\\p{Alnum}{" 35 | + expectedMessageLength + "}"); 36 | } 37 | 38 | @Test 39 | public void testAlphabetic() throws Exception { 40 | testWithUriAndRegex( 41 | "rnd:foo?initialDelay=0&generator=alphabetic&length=" 42 | + expectedMessageLength, "\\p{Alpha}{" 43 | + expectedMessageLength + "}"); 44 | } 45 | 46 | @Test 47 | public void testAscii() throws Exception { 48 | testWithUriAndRegex("rnd:foo?initialDelay=0&generator=ascii&length=" 49 | + expectedMessageLength, "\\p{ASCII}{" + expectedMessageLength 50 | + "}"); 51 | } 52 | 53 | private void testWithUriAndRegex(final String uri, final String regex) 54 | throws Exception { 55 | 56 | context.getRouteDefinitions().get(0).adviceWith(context, 57 | new AdviceWithRouteBuilder() { 58 | @Override 59 | public void configure() throws Exception { 60 | replaceFromWith(uri); 61 | } 62 | }); 63 | 64 | MockEndpoint mockOut = getMockEndpoint("mock:out"); 65 | mockOut.expectedMinimumMessageCount(expectedMessageCount); 66 | 67 | // we expect all message bodies to be an instance of String 68 | mockOut.allMessages().body().isInstanceOf(String.class); 69 | 70 | // we expect all message bodies start with "fired..." text 71 | mockOut.allMessages().body().regex(regex); 72 | 73 | assertMockEndpointsSatisfied(); 74 | } 75 | 76 | @Override 77 | protected RouteBuilder createRouteBuilder() throws Exception { 78 | return new RouteBuilder() { 79 | public void configure() { 80 | from("rnd:foo").to("mock:out"); 81 | } 82 | }; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /camel-rnd/src/test/java/net/javaforge/blog/camel/rnd/test/RndWithAggregatorTest.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.camel.rnd.test; 2 | 3 | import org.apache.camel.Exchange; 4 | import org.apache.camel.Processor; 5 | import org.apache.camel.builder.RouteBuilder; 6 | import org.apache.camel.component.mock.MockEndpoint; 7 | import org.apache.camel.processor.aggregate.AggregationStrategy; 8 | import org.apache.camel.test.junit4.CamelTestSupport; 9 | import org.junit.Test; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class RndWithAggregatorTest extends CamelTestSupport { 15 | 16 | private static final int expectedMessageCount = 20; 17 | 18 | private static final int expectedListSize = 5; 19 | 20 | private static final int expectedMessageLength = 5; 21 | 22 | @Test 23 | public void testAggregatedList() throws Exception { 24 | MockEndpoint mockOut = getMockEndpoint("mock:out"); 25 | mockOut.expectedMinimumMessageCount(expectedMessageCount); 26 | 27 | mockOut.whenAnyExchangeReceived(new Processor() { 28 | 29 | @SuppressWarnings("unchecked") 30 | @Override 31 | public void process(Exchange exchange) throws Exception { 32 | assertNotNull(exchange.getIn().getBody()); 33 | assertIsInstanceOf(List.class, exchange.getIn().getBody()); 34 | assertListSize(exchange.getIn().getBody(List.class), 35 | expectedListSize); 36 | 37 | List data = exchange.getIn().getBody(List.class); 38 | for (String item : data) { 39 | assertNotNull(item); 40 | assertEquals(expectedMessageLength, item.length()); 41 | } 42 | 43 | } 44 | }); 45 | 46 | assertMockEndpointsSatisfied(); 47 | } 48 | 49 | @Override 50 | protected RouteBuilder createRouteBuilder() throws Exception { 51 | return new RouteBuilder() { 52 | public void configure() { 53 | from("rnd:foo?generator=alphanumeric&initialDelay=0&delay=50&length=" + expectedMessageLength) 54 | .setHeader("foo", constant("bar")) 55 | .aggregate(header("foo"), new ListAggregationStrategy()) 56 | .completionSize(expectedListSize) 57 | .to("log:net.javaforge.blog.camel?level=INFO") 58 | .to("mock:out"); 59 | } 60 | }; 61 | } 62 | 63 | private static class ListAggregationStrategy implements AggregationStrategy { 64 | 65 | @SuppressWarnings("unchecked") 66 | @Override 67 | public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { 68 | Object newBody = newExchange.getIn().getBody(); 69 | List list; 70 | if (oldExchange == null) { 71 | list = new ArrayList(); 72 | list.add(newBody); 73 | newExchange.getIn().setBody(list); 74 | return newExchange; 75 | } else { 76 | list = oldExchange.getIn().getBody(List.class); 77 | list.add(newBody); 78 | return oldExchange; 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /camel-rnd/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /dbconf/conf/jetty-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 1 7 | 20 8 | 9 | 10 | 11 | 12 | 13 | 8080 14 | 60000 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /dbconf/conf/jetty-env.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | jdbc/dbconf-app-ds 8 | 9 | 10 | jdbc:h2:dbconf 11 | sa 12 | sa 13 | 14 | 15 | 16 | 17 | 18 | true 19 | 20 | 21 | -------------------------------------------------------------------------------- /dbconf/dbconf.h2.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigpuritz/javaforge-blog/d2cc21f18798f5db6c2d949008633c974c4d0b9c/dbconf/dbconf.h2.db -------------------------------------------------------------------------------- /dbconf/dbconf.trace.db: -------------------------------------------------------------------------------- 1 | 08-28 15:27:23 jdbc[2]: exception 2 | org.h2.jdbc.JdbcSQLException: Value too long for column "VALUE VARCHAR(255)": "STRINGDECODE('\r\n\r\n\r\n\t 5 | 6 | 7 | true 8 | 9 | 10 | 11 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | ') [22001-168] 19 | 09-01 10:30:52 jdbc[2]: exception 20 | org.h2.jdbc.JdbcSQLException: Table "DBCONF" not found; SQL statement: 21 | select * from DBCONF [42102-168] 22 | -------------------------------------------------------------------------------- /dbconf/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | net.javaforge.blog 6 | dbconf 7 | 0.0.1-SNAPSHOT 8 | war 9 | net.javaforge.blog.dbconf 10 | 11 | 12 | 3.0.6.RELEASE 13 | 1.6.6 14 | 1.0.6 15 | 16 | 17 | 18 | 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-compiler-plugin 23 | 2.5.1 24 | 25 | 1.6 26 | 1.6 27 | true 28 | UTF-8 29 | true 30 | true 31 | true 32 | 33 | 34 | 35 | 36 | org.mortbay.jetty 37 | maven-jetty-plugin 38 | 6.1.26 39 | 40 | /dbconf 41 | 5 42 | conf/jetty-config.xml 43 | conf/jetty-env.xml 44 | conf/webdefault.xml 45 | 9966 46 | jetty-stop 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | javax.inject 56 | javax.inject 57 | 1 58 | 59 | 60 | org.slf4j 61 | slf4j-api 62 | ${slf4j.version} 63 | 64 | 65 | org.slf4j 66 | jul-to-slf4j 67 | ${slf4j.version} 68 | 69 | 70 | org.slf4j 71 | jcl-over-slf4j 72 | ${slf4j.version} 73 | 74 | 75 | ch.qos.logback 76 | logback-classic 77 | ${logback.version} 78 | 79 | 80 | ch.qos.logback 81 | logback-access 82 | ${logback.version} 83 | 84 | 85 | org.springframework 86 | spring-context 87 | ${spring.version} 88 | 89 | 90 | commons-logging 91 | commons-logging 92 | 93 | 94 | 95 | 96 | org.springframework 97 | spring-context-support 98 | ${spring.version} 99 | 100 | 101 | commons-logging 102 | commons-logging 103 | 104 | 105 | 106 | 107 | org.springframework 108 | spring-web 109 | ${spring.version} 110 | 111 | 112 | commons-logging 113 | commons-logging 114 | 115 | 116 | 117 | 118 | org.springframework 119 | spring-jdbc 120 | ${spring.version} 121 | 122 | 123 | commons-logging 124 | commons-logging 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | com.h2database 133 | h2 134 | 1.3.168 135 | 136 | 137 | 138 | javax.servlet 139 | servlet-api 140 | 2.5 141 | provided 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /dbconf/readme.txt: -------------------------------------------------------------------------------- 1 | create table t_dbconf_app_props(key varchar2 (100) not null, value varchar2(1000) not null) ; 2 | 3 | insert into t_dbconf_app_props ( key , value ) values ('app.name', 'dbconf'); 4 | insert into t_dbconf_app_props ( key , value ) values ('app.version', '0.0.1'); 5 | insert into t_dbconf_app_props ( key , value ) values ('app.logback.config', ' 6 | 7 | 8 | true 9 | 10 | 11 | 12 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 13 | 14 | 15 | 16 | 17 | 18 | '); -------------------------------------------------------------------------------- /dbconf/src/main/java/net/javaforge/blog/dbconf/ApplicationProperties.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.dbconf; 2 | 3 | import java.util.Properties; 4 | 5 | /** 6 | * Class holding application properties. 7 | */ 8 | public final class ApplicationProperties extends Properties { 9 | 10 | private static final long serialVersionUID = 1L; 11 | 12 | private static ApplicationProperties instance; 13 | 14 | private ApplicationProperties() { 15 | } 16 | 17 | public String getLogbackConfiguration() { 18 | return this.getProperty("app.logback.config"); 19 | } 20 | 21 | public static final ApplicationProperties get() { 22 | if (instance == null) 23 | instance = new ApplicationProperties(); 24 | 25 | return instance; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /dbconf/src/main/java/net/javaforge/blog/dbconf/ApplicationPropertiesInitializer.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.dbconf; 2 | 3 | import java.util.Properties; 4 | 5 | import javax.servlet.ServletContext; 6 | import javax.servlet.ServletContextEvent; 7 | import javax.servlet.ServletContextListener; 8 | 9 | public abstract class ApplicationPropertiesInitializer implements 10 | ServletContextListener { 11 | 12 | @Override 13 | public void contextInitialized(ServletContextEvent sce) { 14 | final ServletContext ctx = sce.getServletContext(); 15 | ctx.log("*************************************************************"); 16 | ctx.log("** app startup **"); 17 | ctx.log("*************************************************************"); 18 | 19 | ApplicationProperties.get().putAll(loadProperties()); 20 | } 21 | 22 | /** 23 | * Loads properties from the desired data source (e.g. database, LDAP,...) 24 | * 25 | * @return initialised properties instance 26 | */ 27 | protected abstract Properties loadProperties(); 28 | 29 | @Override 30 | public void contextDestroyed(ServletContextEvent sce) { 31 | final ServletContext ctx = sce.getServletContext(); 32 | ctx.log("*************************************************************"); 33 | ctx.log("** app shutdown **"); 34 | ctx.log("*************************************************************"); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /dbconf/src/main/java/net/javaforge/blog/dbconf/DatabaseAwareApplicationPropertiesInitializer.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.dbconf; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | import java.util.Properties; 6 | 7 | import javax.sql.DataSource; 8 | 9 | import org.springframework.jdbc.core.JdbcTemplate; 10 | import org.springframework.jdbc.core.RowCallbackHandler; 11 | import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup; 12 | 13 | /** 14 | * Loads application configuration from the database 15 | */ 16 | public class DatabaseAwareApplicationPropertiesInitializer extends 17 | ApplicationPropertiesInitializer { 18 | 19 | private static final String DATASOURCE_KEY = "dbconf.app.ds"; 20 | 21 | private static final String DATASOURCE_FALLBACK_VALUE = "jdbc/dbconf-app-ds"; 22 | 23 | private static final String LOAD_CONFIG_QUERY = "select key, value from t_dbconf_app_props"; 24 | 25 | @Override 26 | protected Properties loadProperties() { 27 | return loadProperties(resolveDataSourceName()); 28 | } 29 | 30 | /** 31 | * Default implementation resolves the name of the data source from the 32 | * system property. You can override this method and resolve the name from 33 | * other sources (e.g. webapp context parameter, property file, environment, 34 | * ...) 35 | * 36 | * @return name of the data source to use 37 | */ 38 | protected String resolveDataSourceName() { 39 | return System.getProperty(DATASOURCE_KEY, DATASOURCE_FALLBACK_VALUE); 40 | } 41 | 42 | /** 43 | * Initialises {@link Properties} instance from the given data source. 44 | * 45 | * @param dataSourceName 46 | * is a name of the data source to use 47 | * @return initialised properties 48 | */ 49 | private Properties loadProperties(String dataSourceName) { 50 | 51 | JndiDataSourceLookup lookup = new JndiDataSourceLookup(); 52 | DataSource ds = lookup.getDataSource(dataSourceName); 53 | 54 | final Properties props = new Properties(); 55 | new JdbcTemplate(ds).query(LOAD_CONFIG_QUERY, new RowCallbackHandler() { 56 | @Override 57 | public void processRow(ResultSet rs) throws SQLException { 58 | props.setProperty(rs.getString("key"), rs.getString("value")); 59 | } 60 | }); 61 | 62 | // additionally we have to add data source name itself to the properties 63 | props.setProperty(DATASOURCE_KEY, dataSourceName); 64 | return props; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /dbconf/src/main/java/net/javaforge/blog/dbconf/LogbackInitializer.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.dbconf; 2 | 3 | import java.io.ByteArrayInputStream; 4 | 5 | import javax.servlet.ServletContextEvent; 6 | import javax.servlet.ServletContextListener; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.slf4j.bridge.SLF4JBridgeHandler; 11 | 12 | import ch.qos.logback.classic.LoggerContext; 13 | import ch.qos.logback.classic.joran.JoranConfigurator; 14 | import ch.qos.logback.core.joran.spi.JoranException; 15 | import ch.qos.logback.core.util.StatusPrinter; 16 | 17 | public class LogbackInitializer implements ServletContextListener { 18 | 19 | private static final Logger LOG = LoggerFactory 20 | .getLogger(LogbackInitializer.class); 21 | 22 | @Override 23 | public void contextInitialized(ServletContextEvent sce) { 24 | 25 | SLF4JBridgeHandler.install(); 26 | 27 | String logbackConfig = ApplicationProperties.get() 28 | .getLogbackConfiguration(); 29 | 30 | if (logbackConfig == null || logbackConfig.isEmpty()) { 31 | sce.getServletContext() 32 | .log("WARNING! No logback configuration found! " 33 | + "Please configure 'app.logback.config' configuration property!"); 34 | } else { 35 | 36 | LoggerContext context = (LoggerContext) LoggerFactory 37 | .getILoggerFactory(); 38 | try { 39 | 40 | JoranConfigurator configurator = new JoranConfigurator(); 41 | configurator.setContext(context); 42 | // Call context.reset() to clear any previous configuration, 43 | // e.g. default configuration. For multi-step configuration, 44 | // omit calling context.reset(). 45 | context.reset(); 46 | configurator.doConfigure(new ByteArrayInputStream(logbackConfig 47 | .getBytes())); 48 | 49 | StatusPrinter.printInCaseOfErrorsOrWarnings(context); 50 | LOG.info("Logback logger configured successfully..."); 51 | 52 | } catch (JoranException e) { 53 | sce.getServletContext().log("Error configuring logback!", e); 54 | } 55 | 56 | } 57 | 58 | } 59 | 60 | @Override 61 | public void contextDestroyed(ServletContextEvent sce) { 62 | 63 | LOG.info("Destroying logback logger context..."); 64 | 65 | LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 66 | lc.stop(); 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /dbconf/src/main/java/net/javaforge/blog/dbconf/beans/AppInfoBean.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.dbconf.beans; 2 | 3 | import javax.inject.Named; 4 | 5 | import org.springframework.beans.factory.annotation.Value; 6 | 7 | @Named("appInfo") 8 | public class AppInfoBean { 9 | 10 | @Value("${app.name}") 11 | private String appName; 12 | 13 | @Value("${app.version}") 14 | private String appVersion; 15 | 16 | public String getAppName() { 17 | return this.appName; 18 | } 19 | 20 | public String getAppVersion() { 21 | return this.appVersion; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /dbconf/src/main/resources/META-INF/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | -------------------------------------------------------------------------------- /dbconf/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | dbconf sample application 8 | 9 | 10 | contextConfigLocation 11 | classpath:META-INF/applicationContext.xml 12 | 13 | 14 | 15 | net.javaforge.blog.dbconf.DatabaseAwareApplicationPropertiesInitializer 16 | 17 | 18 | 19 | net.javaforge.blog.dbconf.LogbackInitializer 20 | 21 | 22 | 23 | org.springframework.web.context.ContextLoaderListener 24 | 25 | 26 | 27 | logback.status.servlet 28 | ch.qos.logback.classic.ViewStatusMessagesServlet 29 | 30 | 31 | 32 | logback.status.servlet 33 | /status/logback 34 | 35 | 36 | 37 | index.jsp 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /dbconf/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@page import="net.javaforge.blog.dbconf.beans.AppInfoBean"%> 2 | <%@page import="org.springframework.web.context.WebApplicationContext"%> 3 | <%@ page 4 | import="org.springframework.web.context.support.WebApplicationContextUtils"%> 5 | <% 6 | WebApplicationContext ctx = WebApplicationContextUtils 7 | .getRequiredWebApplicationContext(request.getSession() 8 | .getServletContext()); 9 | AppInfoBean bean = (AppInfoBean) ctx.getBean("appInfo"); 10 | %> 11 | 12 | 13 | 14 | dbconf example page 15 | 21 | 22 | 23 | 24 |

AppInfoBean properties loaded as values from the database:

25 |
    26 |
  • Application name: <%=bean.getAppName()%>
  • 27 |
  • Application version: <%=bean.getAppVersion()%>
  • 28 |
29 |
30 | click here to see logback status 31 | 32 | -------------------------------------------------------------------------------- /docbkx/conf/customization-fopdf.xsl: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | images/draft.png 9 | 10 | 11 | 14 | 15 | 16 | 17 | 0 18 | 0 19 | 0 20 | 21 | 22 | 5mm 23 | 10mm 24 | 10mm 25 | 26 | 15mm 27 | 10mm 28 | 0mm 29 | 30 | 18mm 31 | 18mm 32 | 33 | 34 | 0pc 35 | 36 | 39 | 40 | 41 | justify 42 | false 43 | 44 | 45 | 11 46 | 8 47 | 48 | 49 | 1.4 50 | 51 | 52 | 53 | 54 | 55 | 56 | 0.8em 57 | 58 | 59 | 60 | 61 | 62 | page 63 | 64 | 65 | 66 | 67 | page 68 | 69 | 70 | 71 | 72 | page 73 | 74 | 75 | 76 | 2 77 | 78 | 79 | 80 | 81 | 82 | 83 | Courier 84 | 8pt 85 | always 86 | 87 | 88 | 89 | 90 | 91 | #E8E8E8 92 | 0.5pt 93 | solid 94 | #575757 95 | 3pt 96 | 97 | 98 | 99 | 100 | 101 | 90 102 | 103 | 104 | -------------------------------------------------------------------------------- /docbkx/docbkx.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 37 | 195 | 209 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /docbkx/docs/bibliography.inc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | References 4 | 5 | 6 | AhoSethiUllman96 7 | 8 | 9 | Alfred V. 10 | Aho 11 | 12 | 13 | Ravi 14 | Sethi 15 | 16 | 17 | Jeffrey D. 18 | Ullman 19 | 20 | 21 | 22 | 1996 23 | Bell Telephone Laboratories, Inc. 24 | 25 | 26 | James T. 27 | DeWolf 28 | 29 | 0-201-10088-6 30 | 31 | Addison-Wesley Publishing Company 32 | 33 | Compilers, Principles, Techniques, and Tools 34 | 35 | 36 | 37 | XML 1.0 38 | Tim Bray, 39 | Jean Paoli, C. M. Sperberg-McQueen, and Eve Maler, editors. 40 | 41 | Extensible Markup 42 | Language (XML) 1.0 Second Edition 43 | 44 | . 45 | World Wide Web Consortium, 2000. 46 | 47 | 48 | 49 | Namespaces 50 | Tim Bray, 51 | Dave Hollander, 52 | and Andrew Layman, editors. 53 | 54 | Namespaces in 55 | XML 56 | 57 | . 58 | World Wide Web Consortium, 1999. 59 | 60 | 61 | -------------------------------------------------------------------------------- /docbkx/docs/images/draft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigpuritz/javaforge-blog/d2cc21f18798f5db6c2d949008633c974c4d0b9c/docbkx/docs/images/draft.png -------------------------------------------------------------------------------- /docbkx/docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigpuritz/javaforge-blog/d2cc21f18798f5db6c2d949008633c974c4d0b9c/docbkx/docs/images/logo.png -------------------------------------------------------------------------------- /docbkx/docs/manual.xml: -------------------------------------------------------------------------------- 1 | 2 | //"> 4 | ]> 5 | 8 | 9 | 10 | $$Id$$ 11 | &root; 12 | 13 | 14 | Documentation for <?eval ${project.name}?> 15 | 16 | 17 | 18 | John 19 | Doe 20 | 21 | 22 | Adam 23 | Surname 24 | 25 | Company, Inc. 26 | 27 | 28 | 29 | Eve 30 | Surname 31 | 32 | Company, Inc. 33 | 34 | 35 | 36 | 2012-01-01 37 | 38 | 39 | 40 | Company Inc. [COMPANY, INC.]. All Rights Reserved. 41 | 42 | 43 | 44 | This is a documentation example generated with Docbook for project 45 | (v. 46 | ). 47 | 48 | 49 | 50 | 51 | Please send comments on this specification to the 52 | docbook-publishers@company.com 53 | list. 54 | 55 | 56 | 57 | 58 | Copyright © COMPANY® 59 | . All Rights Reserved. 60 | 61 | This document and the information contained herein is provided 62 | on an "AS IS" basis 63 | and Company Inc. 64 | DISCLAIMS ALL WARRANTIES, EXPRESS 65 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO 66 | ANY WARRANTY THAT THE 67 | USE OF 68 | THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP 69 | RIGHTS OR ANY 70 | IMPLIED WARRANTIES OF 71 | MERCHANTABILITY OR FITNESS FOR A PARTICULAR 72 | PURPOSE. 73 | 74 | 75 | 76 | 77 | Permission to use, copy, modify and distribute 78 | the DocBook DTD 79 | and its accompanying documentation for any purpose and 80 | without fee is 81 | hereby granted in perpetuity, provided that the above 82 | copyright 83 | notice and this paragraph appear in all copies. 84 | 85 | 86 | 87 | 88 | 89 | The copyright holders make no representation about the suitability 90 | of 91 | this DTD for any purpose. It is provided 92 | as is 93 | without expressed 94 | or implied warranty. If you modify the DocBook DTD 95 | in any way, except 96 | for 97 | declaring and referencing additional general 98 | entities and declaring 99 | additional 100 | notations, identify your DTD as a 101 | variant of DocBook. 102 | 103 | 104 | 105 | 106 | 107 | 108 | Preface 109 | If you have a preface, put it here. 110 | 111 | 112 | 113 | 114 | 115 | This is a chapter 116 | 117 |
118 | This is a section 119 | This is a paragraph. 120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
129 | 130 | 131 | Revision History 132 | Initial Draft. 11 June 2011. 133 | Revised Draft. 6 October 2011. Usage examples, additional 134 | clarifications added. 135 | 136 | 137 | 138 | 139 | 140 |
141 | -------------------------------------------------------------------------------- /docbkx/docs/section0.inc.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | ]> 5 |
10 | 11 | Introduction 12 | 13 | This is an example for a simple introduction main chapter. This is an 14 | example for a link to 15 | Sourceforge: 16 | SourceForge 17 | . 18 | 19 | 20 |
21 | Terminology 22 | 23 | The key words 24 | must 25 | , 26 | must not 27 | , 28 | required 29 | , 30 | shall 31 | , 32 | shall 33 | not 34 | 35 | , 36 | should 37 | , 38 | should 39 | not 40 | 41 | , 42 | recommended 43 | , 44 | may 45 | , and 46 | optional 47 | in this &standard; 48 | are to be interpreted as 49 | described in 50 | 51 | . Note that for reasons of style, these words 52 | are not capitalized in this document. 53 | 54 |
55 | 56 |
57 | Normative References 58 | 59 | 60 | Donald E. Knuth. 61 | Computers and 62 | Typesetting: Volume B, TeX: The Program 63 | 64 | . Addison-Wesley, 65 | 1986. ISBN 0-201-13437-3. 66 | 67 | 68 | XML 1.0 69 | Tim Bray, 70 | Jean Paoli, C. M. Sperberg-McQueen, and Eve Maler, editors. 71 | 72 | Extensible Markup 73 | Language (XML) 1.0 Second Edition 74 | 75 | 76 | . 77 | World Wide Web Consortium, 2000. 78 | 79 | 80 |
81 | 82 |
-------------------------------------------------------------------------------- /docbkx/docs/section1.inc.xml: -------------------------------------------------------------------------------- 1 | 2 |
7 | 8 | The Dummy Chapter 9 | 10 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et 11 | magna 12 | tellus. In hac 13 | habitasse platea dictumst. Nam aliquam ligula ut 14 | ipsum vehicula et dictum massa 15 | iaculis. Duis vel 16 | lacus nibh, vitae 17 | fermentum neque. Mauris consequat sem pulvinar augue 18 | feugiat accumsan. 19 | Ut in 20 | mauris risus. Etiam sed nulla justo. Sed quis velit eu lacus 21 | ullamcorper 22 | gravida. Nunc justo 23 | libero, ullamcorper eu tempor sed, 24 | interdum quis nisi. Vivamus vitae nibh in 25 | massa rutrum 26 | condimentum. Duis 27 | eget augue vitae sapien auctor eleifend ut eget lectus. Quisque 28 | consectetur, 29 | velit nec facilisis tristique, odio enim blandit mauris, 30 | in euismod enim 31 | magna vitae nunc. 32 | 33 | Example for an ordered lists: 34 | 35 | 36 | List item number 1. 37 | 38 | 39 | One more list item. 40 | 41 | 42 | 43 |
-------------------------------------------------------------------------------- /docbkx/docs/section2.inc.xml: -------------------------------------------------------------------------------- 1 | 2 |
7 | 8 | One more chapter 9 | 10 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et magna tellus. In hac 11 | habitasse platea dictumst. Nam aliquam ligula ut ipsum vehicula et dictum massa iaculis. Duis vel 12 | lacus nibh, vitae fermentum neque. Mauris consequat sem pulvinar augue feugiat accumsan. Ut in 13 | mauris risus. Etiam sed nulla justo. Sed quis velit eu lacus ullamcorper gravida. Nunc justo 14 | libero, ullamcorper eu tempor sed, interdum quis nisi. Vivamus vitae nibh in massa rutrum 15 | condimentum. Duis eget augue vitae sapien auctor eleifend ut eget lectus. Quisque consectetur, 16 | velit nec facilisis tristique, odio enim blandit mauris, in euismod enim magna vitae nunc. 17 | 18 | 19 |
20 | Some more docbook examples 21 | 22 | Example for a variable list: 23 | 24 | 25 | 26 | title 27 | 28 | A name given to the resource. 29 | 30 | 31 | 32 | creator 33 | 34 | An entity primarily responsible for making the resource. Examples of a 35 | Creator include a 36 | person, an organization, or a service. Typically, the 37 | name of a Creator should be used to 38 | indicate the entity. 39 | 40 | 41 | 42 | subject 43 | 44 | The topic of the resource. Typically, the subject will be represented 45 | using keywords, key 46 | phrases, or classification codes. Recommended best 47 | practice is to use a controlled vocabulary. 48 | To describe the spatial or 49 | temporal topic of the resource, use the Coverage element. 50 | 51 | 52 | 53 | description 54 | 55 | An account of the resource. Description may include but is not limited 56 | to: an abstract, a 57 | table of contents, a graphical representation, or a 58 | free-text account of the resource. 59 | 60 | 61 | 62 | publisher 63 | 64 | An entity responsible for making the resource available. Examples of a 65 | Publisher include 66 | a person, an organization, or a service. Typically, 67 | the name of a Publisher should be used to 68 | indicate the entity. 69 | 70 | 71 | 72 | format 73 | 74 | The file format, physical medium, or dimensions of the resource. 75 | Examples of dimensions 76 | include size and duration. Recommended best 77 | practice is to use a controlled vocabulary such as 78 | the list of Internet 79 | Media Types [MIME]. 80 | 81 | 82 | 83 | identifier 84 | 85 | An unambiguous reference to the resource within a given context. 86 | Recommended best 87 | practice is to identify the resource by means of a 88 | string conforming to a formal 89 | identification system. 90 | 91 | 92 | 93 | 94 | The following example provides a table . 95 | 96 | 97 | This is my table title 98 | 99 | 100 | 101 | 102 | 103 | Column 1 element 104 | Columnt 2 element 105 | 106 | 107 | 108 | 109 | 110 | title 111 | 112 | 113 | title 114 | 115 | 116 | 117 | 118 | creator 119 | 120 | 121 | author 122 | , 123 | editor 124 | , 125 | othercredit 126 | 127 | Best practice would be to only use author for creator. Use contributor for other 128 | roles. 129 | 130 | 131 | 132 | 133 | 134 | subject 135 | 136 | 137 | keywordset 138 | , 139 | subjectset 140 | 141 | 142 | 143 | 144 | description 145 | 146 | 147 | abstract 148 | 149 | 150 | 151 | 152 | publisher 153 | 154 | 155 | publisher 156 | , 157 | publishername 158 | 159 | 160 | 161 | 162 | contributor 163 | 164 | 165 | author 166 | , 167 | editor 168 | , 169 | othercredit 170 | , 171 | collab 172 | 173 | 174 | 175 | 176 | language 177 | 178 | 179 | lang 180 | or 181 | xml:lang 182 | attribute 183 | 184 | 185 | 186 | 187 | alternative 188 | 189 | 190 | titleabbrev 191 | 192 | 193 | 194 | 195 | tableOfContents 196 | 197 | 198 | bibliomisc role="toc" 199 | 200 | 201 | 202 | 203 | modified 204 | 205 | 206 | date 207 | role="modified" 208 | , 209 | revhistory 210 | / 211 | revision 212 | 213 | 214 | 215 | 216 |
217 |
218 |
219 | New Element Definitions 220 | The following elements have been added to support the needs of publishers: 221 | 222 | 223 | speaker 224 | 225 | Designates a person who is giving a speech or lecture. 226 | 227 | 228 | 229 | line 230 | 231 | A line of dialogue or other form of communication. 232 | 233 | 234 | 235 | linegroup 236 | 237 | A grouping of lines in dialogue or other form of communication. 238 | 239 | 240 | 241 | poetry 242 | 243 | A container for poetry. 244 | 245 | 246 | 247 | dialogue 248 | 249 | A container for speeches and other forms of communication involving 250 | dialogue. 251 | 252 | 253 | 254 | drama 255 | 256 | A container for plays and other forms of dramatic presentation. 257 | 258 | 259 | 260 | 261 | 262 | Example Dialogue 263 | The following provides an example usage of the newly added elements: 264 | 265 | 267 | 268 | HAMLET 269 | To be, or not to be: that is the 270 | question: 271 | Whether 'tis nobler in the mind to 272 | suffer 273 | The slings and arrows of outrageous 274 | fortune, 275 | Or to take arms 276 | against a sea of 277 | troubles, 278 | And by opposing end them? 279 | 280 | 281 | ]]> 282 | 283 | 284 | Program listing example 1 285 | 287 | Tove 288 | Jani 289 | Reminder 290 | Don't forget me this weekend! 291 | ]]> 292 | 293 | 294 | Program listing example 295 | // note! private property 299 | 300 | } 301 | ]]> 302 | 303 | 304 | 305 | #ifndef _My_Parser_h_ 306 | #define _My_Parser_h_ 307 | #include "MyFetch.h" 308 | class My_Parser 309 | { 310 | public: 311 | // 312 | // Construction/Destruction 313 | // 314 | My_Parser(); 315 | virtual ~My_Parser() = 0; 316 | virtual int parse(MyFetch &fetcher) = 0; 317 | }; 318 | #endif 319 | 320 | 321 | 322 | 323 | Make this conditional. 324 | 325 | 326 | Load necessary constants. 327 | 328 | 329 | Define new class 330 | 331 | 332 | 333 | 334 |
335 |
336 | 337 | -------------------------------------------------------------------------------- /docbkx/docs/section3.inc.xml: -------------------------------------------------------------------------------- 1 | 2 |
7 | 8 | Image examples 9 | 10 | This is an image: 11 |
12 | This is an image title 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
-------------------------------------------------------------------------------- /docbkx/docs/section4.inc.xml: -------------------------------------------------------------------------------- 1 | 2 |
7 | 8 | Conformance 9 | For implementations and/or applications that contain extensions, 10 | extensions SHALL 11 | be clearly 12 | described in supporting documentation, and the extensions 13 | SHALL be marked 14 | as such within the 15 | implementation/application. 16 | This document’s normative language is English. Translation into 17 | other languages 18 | is permitted. 19 | 20 |
-------------------------------------------------------------------------------- /docbkx/manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bigpuritz/javaforge-blog/d2cc21f18798f5db6c2d949008633c974c4d0b9c/docbkx/manual.pdf -------------------------------------------------------------------------------- /docbkx/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | net.javaforge.blog 6 | docbkx 7 | 0.0.1-SNAPSHOT 8 | jar 9 | javaforge docbkx 10 | 11 | 12 | 13 | 14 | org.apache.maven.plugins 15 | maven-compiler-plugin 16 | 2.5.1 17 | 18 | 1.6 19 | 1.6 20 | true 21 | UTF-8 22 | true 23 | true 24 | true 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | docbkx 33 | 34 | 35 | 36 | com.agilejava.docbkx 37 | docbkx-maven-plugin 38 | 2.0.14 39 | 40 | 41 | doc 42 | 43 | generate-pdf 44 | 45 | package 46 | 47 | 48 | 49 | 50 | net.sf.xslthl 51 | xslthl 52 | 2.0.2 53 | runtime 54 | 55 | 56 | net.sf.offo 57 | fop-hyph 58 | 1.2 59 | runtime 60 | 61 | 62 | 63 | docs 64 | target/docs 65 | true 66 | 1 67 | 1 68 | java 69 | 1 70 | A4 71 | 1 72 | ${basedir}/conf/customization-fopdf.xsl 73 | manual.xml 74 | 75 | 77 | 79 | 80 | 81 | 82 | 83 | 84 | org.codehaus.mojo 85 | build-helper-maven-plugin 86 | 1.7 87 | 88 | 89 | 90 | attach-artifact 91 | 92 | package 93 | 94 | 95 | 96 | ${project.build.directory}/${project.artifactId}-${project.version}-docs.zip 97 | zip 98 | docs 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docbkx/src/main/java/net/javaforge/blog/docbkx/App.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.docbkx; 2 | 3 | public class App { 4 | 5 | public static void main(String[] args) { 6 | 7 | System.out.println("Hello World!"); 8 | 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /liquibase-sample/db/ddl/1.x/1.0/db.changelog-1.0.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /liquibase-sample/db/ddl/1.x/1.1/db.changelog-1.1.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /liquibase-sample/db/ddl/1.x/1.2/db.changelog-1.2.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /liquibase-sample/db/ddl/1.x/db.changelog-1.x.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /liquibase-sample/db/ddl/db.changelog-master.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | -------------------------------------------------------------------------------- /liquibase-sample/db/liquibase.properties: -------------------------------------------------------------------------------- 1 | promptOnNonLocalDatabase=false 2 | changeLogFile=db/ddl/db.changelog-master.xml 3 | driver=org.h2.Driver 4 | url=jdbc:h2:liquibase-sample 5 | username=sa 6 | password=sa 7 | #contexts= -------------------------------------------------------------------------------- /liquibase-sample/db/testdata/addresses.csv: -------------------------------------------------------------------------------- 1 | street,house_no,zipcode,city 2 | Lindenstr.,12,12345,Berlin 3 | Baker Str.,534,A-1233,London 4 | 23 Street,1,93992,New York -------------------------------------------------------------------------------- /liquibase-sample/db/testdata/db.testdata.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /liquibase-sample/db/testdata/roles.csv: -------------------------------------------------------------------------------- 1 | name,description 2 | USER,A simple user 3 | ADMIN,Administrator user 4 | ANONYMOUS,NULL -------------------------------------------------------------------------------- /liquibase-sample/db/testdata/users.csv: -------------------------------------------------------------------------------- 1 | id,username,role 2 | 1,foo,USER 3 | 2,bar,ADMIN 4 | 3,xyz,USER -------------------------------------------------------------------------------- /liquibase-sample/liquibase-sample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 42 | 200 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /liquibase-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | net.javaforge.blog 6 | liquibase-sample 7 | 0.0.1-SNAPSHOT 8 | 9 | 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 2.5.1 16 | 17 | 1.6 18 | 1.6 19 | true 20 | UTF-8 21 | true 22 | true 23 | true 24 | 25 | 26 | 27 | 28 | org.liquibase 29 | liquibase-maven-plugin 30 | 2.0.5 31 | 32 | false 33 | db/liquibase.properties 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | org.eclipse.m2e 44 | lifecycle-mapping 45 | 1.0.0 46 | 47 | 48 | 49 | 50 | 51 | org.liquibase 52 | 53 | liquibase-maven-plugin 54 | 55 | 56 | [2.0.5,) 57 | 58 | 59 | update 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | com.h2database 78 | h2 79 | 1.3.168 80 | test 81 | 82 | 83 | 84 | org.liquibase 85 | liquibase-core 86 | 2.0.5 87 | test 88 | 89 | 90 | 91 | junit 92 | junit 93 | 4.10 94 | test 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /liquibase-sample/readme.txt: -------------------------------------------------------------------------------- 1 | 1. Apply all database changes: 2 | 3 | mvn liquibase:update 4 | 5 | 6 | 2. Generate SQL script for applying all database changes 7 | 8 | mvn liquibase:updateSQL 9 | 10 | 11 | 3. Create testdata: 12 | 13 | mvn -Dliquibase.changeLogFile=db/testdata/db.testdata.xml liquibase:update 14 | 15 | 16 | 4. Remove testdata 17 | 18 | mvn -Dliquibase.changeLogFile=db/testdata/db.testdata.xml -Dliquibase.rollbackCount=1000 liquibase:rollback 19 | -------------------------------------------------------------------------------- /liquibase-sample/src/test/java/net/javaforge/blog/liquibase/TestWithLiquibase.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.liquibase; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.PreparedStatement; 6 | import java.sql.ResultSet; 7 | import java.sql.SQLException; 8 | 9 | import liquibase.Liquibase; 10 | import liquibase.database.Database; 11 | import liquibase.database.DatabaseFactory; 12 | import liquibase.database.jvm.JdbcConnection; 13 | import liquibase.exception.LiquibaseException; 14 | import liquibase.resource.FileSystemResourceAccessor; 15 | 16 | import org.junit.AfterClass; 17 | import org.junit.Assert; 18 | import org.junit.BeforeClass; 19 | import org.junit.Test; 20 | 21 | public class TestWithLiquibase { 22 | 23 | private static Connection conn; 24 | 25 | private static Liquibase liquibase; 26 | 27 | @BeforeClass 28 | public static void createTestData() throws SQLException, 29 | ClassNotFoundException, LiquibaseException { 30 | Class.forName("org.h2.Driver"); 31 | conn = DriverManager.getConnection("jdbc:h2:liquibase-sample", "sa", 32 | "sa"); 33 | 34 | Database database = DatabaseFactory.getInstance() 35 | .findCorrectDatabaseImplementation(new JdbcConnection(conn)); 36 | 37 | liquibase = new Liquibase("db/testdata/db.testdata.xml", 38 | new FileSystemResourceAccessor(), database); 39 | liquibase.update(null); 40 | 41 | } 42 | 43 | @AfterClass 44 | public static void removeTestData() throws LiquibaseException, SQLException { 45 | liquibase.rollback(1000, null); 46 | conn.close(); 47 | } 48 | 49 | @Test 50 | public void testUsers() throws SQLException { 51 | PreparedStatement stmt = null; 52 | ResultSet rs = null; 53 | try { 54 | 55 | stmt = conn 56 | .prepareStatement("select count(*) as numberOfUsers from t_user"); 57 | rs = stmt.executeQuery(); 58 | rs.next(); 59 | int numberOfUsers = rs.getInt("numberOfUsers"); 60 | Assert.assertEquals(3, numberOfUsers); 61 | 62 | } finally { 63 | rs.close(); 64 | stmt.close(); 65 | } 66 | } 67 | 68 | @Test 69 | public void testRoles() throws SQLException { 70 | 71 | PreparedStatement stmt = null; 72 | ResultSet rs = null; 73 | try { 74 | 75 | stmt = conn 76 | .prepareStatement("select count(*) as numberOfRoles from t_role"); 77 | rs = stmt.executeQuery(); 78 | rs.next(); 79 | int numberOfUsers = rs.getInt("numberOfRoles"); 80 | Assert.assertEquals(3, numberOfUsers); 81 | 82 | } finally { 83 | rs.close(); 84 | stmt.close(); 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /restgwt-groovy/GenerateRestAsyncResources.groovy: -------------------------------------------------------------------------------- 1 | import japa.parser.* 2 | import japa.parser.ast.* 3 | import japa.parser.ast.body.MethodDeclaration; 4 | import japa.parser.ast.body.ModifierSet; 5 | import japa.parser.ast.body.TypeDeclaration; 6 | 7 | def engine = new groovy.text.SimpleTemplateEngine() 8 | def utilClassTmpl = engine.createTemplate(''' 9 | 10 | /** 11 | * Utility class to get the instance of the Rest Service 12 | */ 13 | public static final class Util { 14 | 15 | private static ${asyncResourceClass} instance; 16 | 17 | public static final ${asyncResourceClass} get() { 18 | if (instance == null) { 19 | instance = com.google.gwt.core.client.GWT.create(${asyncResourceClass}.class); 20 | ((org.fusesource.restygwt.client.RestServiceProxy) instance).setResource( 21 | new org.fusesource.restygwt.client.Resource(${asyncResourcePath}) 22 | ); 23 | } 24 | return instance; 25 | } 26 | 27 | private Util() { 28 | // Utility class should not be instantiated 29 | } 30 | } 31 | 32 | ''') 33 | 34 | def methodTmpl = engine.createTemplate(''' 35 | ${methodAnnotations} 36 | public void ${methodName}(${methodParams}${methodCallback});\n 37 | ''') 38 | 39 | def restAsyncResourcesPath = project.properties['restAsyncResourcesPath'] 40 | def restAsyncResourcesPackage = project.properties['restAsyncResourcesPackage'] 41 | def restResourcesPath = project.properties['restResourcesPath'] 42 | def restURLBase = project.properties['restURLBase'] 43 | def importsRegexp = ~project.properties['importsRegexp'] 44 | 45 | new File(restResourcesPath).eachFileMatch(~/.*?\.java/) { file -> 46 | 47 | println "Reading: ${file.absolutePath}" 48 | 49 | FileInputStream _in = new FileInputStream(file) 50 | CompilationUnit cu; 51 | try { 52 | 53 | cu = JavaParser.parse(_in) 54 | TypeDeclaration resource = cu.types.first(); 55 | 56 | def pathAnnotation = resource.annotations.find { it instanceof japa.parser.ast.expr.SingleMemberAnnotationExpr && it.name.toString().equals("Path") } 57 | def asyncResourcePath = "\"${restURLBase}${pathAnnotation.memberValue.toString()[1..-1]}" 58 | def asyncResourceClass = "${resource.name}Async" 59 | 60 | println "Writing: ${asyncResourceClass}.java" 61 | 62 | File baseDir = new File(restAsyncResourcesPath); 63 | baseDir.mkdirs(); 64 | 65 | File target = new File(baseDir, "${asyncResourceClass}.java") 66 | if (target.exists()) target.delete(); 67 | 68 | target << ("package ${restAsyncResourcesPackage};\n\n") 69 | 70 | cu.imports.each() { 71 | if (importsRegexp.matcher(it.name.toString()).matches()) 72 | target << ("$it") 73 | } 74 | 75 | target << ("\n") 76 | target << ("public interface $asyncResourceClass extends org.fusesource.restygwt.client.RestService {\n") 77 | 78 | resource.members.each() { member -> 79 | if (member instanceof MethodDeclaration && ModifierSet.isPublic(member.modifiers)) { 80 | def mAnnotations = "" 81 | member.annotations.each { ann -> mAnnotations += "${ann} " } 82 | def methodParams = "" 83 | member.parameters.each { param -> methodParams += "${param}, " } 84 | def methodCallback = "org.fusesource.restygwt.client.MethodCallback<" + (member.type instanceof japa.parser.ast.type.VoidType ? "Void" : member.type.toString()) + "> callback" 85 | target << (methodTmpl.make(["methodAnnotations": mAnnotations, "methodName": member.name.toString(), "methodParams": methodParams, "methodCallback": methodCallback]).toString()) 86 | } 87 | } 88 | 89 | target << (utilClassTmpl.make(["asyncResourceClass": asyncResourceClass, "asyncResourcePath": asyncResourcePath]).toString()) 90 | target << ("}") 91 | 92 | } catch (Throwable t) { 93 | 94 | t.printStackTrace() 95 | 96 | } finally { 97 | 98 | _in.close(); 99 | } 100 | } -------------------------------------------------------------------------------- /restgwt-groovy/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | net.javaforge.blog 6 | restgwt-groovy 7 | 0.0.1-SNAPSHOT 8 | war 9 | net.javaforge.blog.restgwt-groovy 10 | 11 | 12 | 2.4.0 13 | 1.6.6 14 | 1.13 15 | 3.3.1 16 | 1.2 17 | ${project.build.directory}/${project.build.finalName} 18 | UTF-8 19 | 20 | 21 | 22 | 23 | com.google.gwt 24 | gwt-servlet 25 | ${gwt.version} 26 | runtime 27 | 28 | 29 | com.sun.jersey 30 | jersey-bundle 31 | ${jersey.version} 32 | 33 | 34 | com.sun.jersey 35 | jersey-json 36 | ${jersey.version} 37 | 38 | 39 | asm 40 | asm 41 | ${asm.version} 42 | 43 | 44 | org.fusesource.restygwt 45 | restygwt 46 | ${restygwt.version} 47 | 48 | 49 | org.slf4j 50 | slf4j-api 51 | ${slf4j.version} 52 | 53 | 54 | org.slf4j 55 | slf4j-simple 56 | ${slf4j.version} 57 | 58 | 59 | com.google.gwt 60 | gwt-user 61 | ${gwt.version} 62 | provided 63 | 64 | 65 | 66 | 67 | 68 | ${webappDirectory}/WEB-INF/classes 69 | 70 | 71 | 72 | 73 | org.codehaus.mojo 74 | build-helper-maven-plugin 75 | 1.7 76 | 77 | 78 | add-source 79 | generate-sources 80 | 81 | add-source 82 | 83 | 84 | 85 | ${basedir}/src/gen/java 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | org.codehaus.gmaven 94 | gmaven-plugin 95 | 1.4 96 | 97 | 98 | create-async-rest-services 99 | generate-sources 100 | 101 | execute 102 | 103 | 104 | 105 | ${basedir}/src/main/java/net/javaforge/gwt/rest/server/remote/rest 106 | 107 | 108 | ${basedir}/src/gen/java/net/javaforge/gwt/rest/client/remote/rest 109 | 110 | net.javaforge.gwt.rest.client.remote.rest 111 | 112 | rest 113 | net\.javaforge\..*|java\..*|javax\.ws\.rs.* 114 | 115 | 116 | 117 | com.google.code.javaparser 118 | javaparser 119 | 1.0.8 120 | 121 | 122 | ${basedir}/GenerateRestAsyncResources.groovy 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | org.codehaus.mojo 131 | gwt-maven-plugin 132 | 2.4.0 133 | 134 | 135 | 136 | compile 137 | test 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 148 | 149 | ${basedir}/src/gen/java 150 | ../rpc/{0} 151 | App.html 152 | ${webappDirectory} 153 | 154 | 155 | 156 | 157 | 158 | 159 | org.apache.maven.plugins 160 | maven-war-plugin 161 | 2.1.1 162 | 163 | 164 | compile 165 | 166 | exploded 167 | 168 | 169 | 170 | 171 | ${webappDirectory} 172 | 173 | 174 | 175 | org.apache.maven.plugins 176 | maven-compiler-plugin 177 | 2.5.1 178 | 179 | 1.6 180 | 1.6 181 | true 182 | UTF-8 183 | true 184 | true 185 | true 186 | 187 | 188 | 189 | 190 | 191 | 193 | 194 | org.eclipse.m2e 195 | lifecycle-mapping 196 | 1.0.0 197 | 198 | 199 | 200 | 201 | 202 | 203 | org.codehaus.mojo 204 | 205 | 206 | gwt-maven-plugin 207 | 208 | 209 | [2.4.0,) 210 | 211 | 212 | generateAsync 213 | i18n 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | org.codehaus.gmaven 224 | 225 | 226 | gmaven-plugin 227 | 228 | 229 | [1.4,) 230 | 231 | 232 | execute 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /restgwt-groovy/src/main/java/net/javaforge/gwt/rest/client/App.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.gwt.rest.client; 2 | 3 | import com.google.gwt.core.client.EntryPoint; 4 | import com.google.gwt.event.dom.client.ClickEvent; 5 | import com.google.gwt.event.dom.client.ClickHandler; 6 | import com.google.gwt.user.client.Window; 7 | import com.google.gwt.user.client.ui.Button; 8 | import com.google.gwt.user.client.ui.FlexTable; 9 | import com.google.gwt.user.client.ui.RootPanel; 10 | import net.javaforge.gwt.rest.client.remote.rest.PersonResourceAsync; 11 | import net.javaforge.gwt.rest.shared.domain.Person; 12 | import org.fusesource.restygwt.client.Defaults; 13 | import org.fusesource.restygwt.client.Method; 14 | import org.fusesource.restygwt.client.MethodCallback; 15 | 16 | import java.util.List; 17 | 18 | public class App implements EntryPoint { 19 | 20 | private FlexTable personsTable; 21 | 22 | static { 23 | // if you don't do this, on JSON response you'll get something like 24 | // this: 25 | // "Could not parse response: org.fusesource.restygwt.client.ResponseFormatException: Response was NOT a valid JSON document" 26 | Defaults.setDateFormat(null); 27 | } 28 | 29 | @Override 30 | public void onModuleLoad() { 31 | 32 | Button button = new Button("load persons"); 33 | button.addClickHandler(new ClickHandler() { 34 | 35 | @Override 36 | public void onClick(ClickEvent event) { 37 | loadPersons(); 38 | } 39 | }); 40 | 41 | personsTable = new FlexTable(); 42 | personsTable.setCellPadding(1); 43 | personsTable.setCellSpacing(0); 44 | personsTable.setWidth("600px"); 45 | 46 | RootPanel.get().add(button); 47 | RootPanel.get().add(personsTable); 48 | 49 | } 50 | 51 | private void loadPersons() { 52 | 53 | PersonResourceAsync.Util.get().getPersons( 54 | new MethodCallback>() { 55 | 56 | @Override 57 | public void onSuccess(Method method, List persons) { 58 | if (personsTable.getRowCount() == 0) { // add header 59 | personsTable.setText(0, 0, "ID"); 60 | personsTable.setText(0, 1, "NAME"); 61 | personsTable.setText(0, 2, "DATE OF BIRTH"); 62 | personsTable.getRowFormatter().addStyleName(0, 63 | "tableHeader"); 64 | } 65 | 66 | for (Person p : persons) { 67 | int rowNum = personsTable.getRowCount(); 68 | personsTable.setText(rowNum, 0, 69 | String.valueOf(p.getId())); 70 | personsTable.setText(rowNum, 1, p.getName()); 71 | personsTable.setText(rowNum, 2, 72 | String.valueOf(p.getDateOfBirth())); 73 | } 74 | } 75 | 76 | @Override 77 | public void onFailure(Method method, Throwable exception) { 78 | Window.alert("Error while loading persons! Cause: " 79 | + exception.getMessage()); 80 | } 81 | }); 82 | 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /restgwt-groovy/src/main/java/net/javaforge/gwt/rest/server/remote/rest/PersonResource.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.gwt.rest.server.remote.rest; 2 | 3 | import net.javaforge.gwt.rest.shared.domain.Person; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.ws.rs.GET; 8 | import javax.ws.rs.Path; 9 | import javax.ws.rs.PathParam; 10 | import javax.ws.rs.Produces; 11 | import javax.ws.rs.core.MediaType; 12 | import java.util.ArrayList; 13 | import java.util.Date; 14 | import java.util.List; 15 | 16 | @Path("/person") 17 | public class PersonResource { 18 | 19 | private static final Logger logger = LoggerFactory 20 | .getLogger(PersonResource.class); 21 | 22 | private static int counter = 1; 23 | 24 | @GET 25 | @Produces(MediaType.APPLICATION_JSON) 26 | public List getPersons() { 27 | 28 | List persons = new ArrayList(); 29 | for (int i = 0; i < 5; i++) { 30 | persons.add(new Person(counter, "name-" + counter, new Date())); 31 | counter++; 32 | } 33 | 34 | logger.info("Returning {} persons...", persons.size()); 35 | 36 | return persons; 37 | } 38 | 39 | @GET 40 | @Path("book/{id}") 41 | public void doPersons(@PathParam("id") String isbn) { 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /restgwt-groovy/src/main/java/net/javaforge/gwt/rest/shared/domain/Person.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.gwt.rest.shared.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class Person { 6 | 7 | private int id; 8 | 9 | private String name; 10 | 11 | private Date dateOfBirth; 12 | 13 | public Person() { 14 | } 15 | 16 | public Person(int id, String name, Date dateOfBirth) { 17 | this.id = id; 18 | this.name = name; 19 | this.dateOfBirth = dateOfBirth; 20 | } 21 | 22 | public int getId() { 23 | return this.id; 24 | } 25 | 26 | public String getName() { 27 | return this.name; 28 | } 29 | 30 | public Date getDateOfBirth() { 31 | return this.dateOfBirth; 32 | } 33 | 34 | public void setId(int id) { 35 | this.id = id; 36 | } 37 | 38 | public void setName(String name) { 39 | this.name = name; 40 | } 41 | 42 | public void setDateOfBirth(Date dateOfBirth) { 43 | this.dateOfBirth = dateOfBirth; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "Person [id=" + this.id + ", name=" + this.name 49 | + ", dateOfBirth=" + this.dateOfBirth + "]"; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /restgwt-groovy/src/main/resources/net/javaforge/gwt/rest/App.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /restgwt-groovy/src/main/webapp/App.css: -------------------------------------------------------------------------------- 1 | *, body { 2 | font-size: 10px; 3 | font-family: sans-serif; 4 | } 5 | 6 | .tableHeader { 7 | background-color: #CCCCCC; 8 | color: #FFFFFF; 9 | } -------------------------------------------------------------------------------- /restgwt-groovy/src/main/webapp/App.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Web Application Starter Project 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /restgwt-groovy/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | jersey-rest 10 | com.sun.jersey.spi.container.servlet.ServletContainer 11 | 12 | com.sun.jersey.config.property.packages 13 | net.javaforge.gwt.rest.server.remote.rest 14 | 15 | 16 | com.sun.jersey.api.json.POJOMappingFeature 17 | true 18 | 19 | 1 20 | 21 | 22 | 23 | jersey-rest 24 | /rest/* 25 | 26 | 27 | 28 | 29 | App.html 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /restgwt/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | net.javaforge.blog 6 | restgwt 7 | 0.0.1-SNAPSHOT 8 | war 9 | net.javaforge.blog.restgwt 10 | 11 | 12 | 2.4.0 13 | 1.6.6 14 | 1.13 15 | 3.3.1 16 | 1.2 17 | ${project.build.directory}/${project.build.finalName} 18 | UTF-8 19 | 20 | 21 | 22 | 23 | com.google.gwt 24 | gwt-servlet 25 | ${gwt.version} 26 | runtime 27 | 28 | 29 | com.sun.jersey 30 | jersey-bundle 31 | ${jersey.version} 32 | 33 | 34 | com.sun.jersey 35 | jersey-json 36 | ${jersey.version} 37 | 38 | 39 | asm 40 | asm 41 | ${asm.version} 42 | 43 | 44 | org.fusesource.restygwt 45 | restygwt 46 | ${restygwt.version} 47 | 48 | 49 | org.slf4j 50 | slf4j-api 51 | ${slf4j.version} 52 | 53 | 54 | org.slf4j 55 | slf4j-simple 56 | ${slf4j.version} 57 | 58 | 59 | com.google.gwt 60 | gwt-user 61 | ${gwt.version} 62 | provided 63 | 64 | 65 | 66 | 67 | 68 | ${webappDirectory}/WEB-INF/classes 69 | 70 | 71 | 72 | 73 | org.codehaus.mojo 74 | gwt-maven-plugin 75 | 2.4.0 76 | 77 | 78 | 79 | compile 80 | test 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 90 | 91 | ${basedir}/src/gen/java 92 | ../rpc/{0} 93 | App.html 94 | ${webappDirectory} 95 | 96 | 97 | 98 | 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-war-plugin 103 | 2.1.1 104 | 105 | 106 | compile 107 | 108 | exploded 109 | 110 | 111 | 112 | 113 | ${webappDirectory} 114 | 115 | 116 | 117 | org.apache.maven.plugins 118 | maven-compiler-plugin 119 | 2.5.1 120 | 121 | 1.6 122 | 1.6 123 | true 124 | UTF-8 125 | true 126 | true 127 | true 128 | 129 | 130 | 131 | 132 | 133 | 135 | 136 | org.eclipse.m2e 137 | lifecycle-mapping 138 | 1.0.0 139 | 140 | 141 | 142 | 143 | 144 | 145 | org.codehaus.mojo 146 | 147 | 148 | gwt-maven-plugin 149 | 150 | 151 | [2.4.0,) 152 | 153 | 154 | generateAsync 155 | i18n 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /restgwt/src/main/java/net/javaforge/gwt/rest/client/App.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.gwt.rest.client; 2 | 3 | import com.google.gwt.core.client.EntryPoint; 4 | import com.google.gwt.event.dom.client.ClickEvent; 5 | import com.google.gwt.event.dom.client.ClickHandler; 6 | import com.google.gwt.user.client.Window; 7 | import com.google.gwt.user.client.ui.Button; 8 | import com.google.gwt.user.client.ui.FlexTable; 9 | import com.google.gwt.user.client.ui.RootPanel; 10 | import net.javaforge.gwt.rest.client.remote.rest.PersonResourceAsync; 11 | import net.javaforge.gwt.rest.shared.domain.Person; 12 | import org.fusesource.restygwt.client.Defaults; 13 | import org.fusesource.restygwt.client.Method; 14 | import org.fusesource.restygwt.client.MethodCallback; 15 | 16 | import java.util.List; 17 | 18 | public class App implements EntryPoint { 19 | 20 | private FlexTable personsTable; 21 | 22 | static { 23 | // if you don't do this, on JSON response you'll get something like 24 | // this: 25 | // "Could not parse response: org.fusesource.restygwt.client.ResponseFormatException: Response was NOT a valid JSON document" 26 | Defaults.setDateFormat(null); 27 | } 28 | 29 | @Override 30 | public void onModuleLoad() { 31 | 32 | Button button = new Button("load persons"); 33 | button.addClickHandler(new ClickHandler() { 34 | 35 | @Override 36 | public void onClick(ClickEvent event) { 37 | loadPersons(); 38 | } 39 | }); 40 | 41 | personsTable = new FlexTable(); 42 | personsTable.setCellPadding(1); 43 | personsTable.setCellSpacing(0); 44 | personsTable.setWidth("600px"); 45 | 46 | RootPanel.get().add(button); 47 | RootPanel.get().add(personsTable); 48 | 49 | } 50 | 51 | private void loadPersons() { 52 | 53 | PersonResourceAsync.Util.get().getPersons( 54 | new MethodCallback>() { 55 | 56 | @Override 57 | public void onSuccess(Method method, List persons) { 58 | if (personsTable.getRowCount() == 0) { // add header 59 | personsTable.setText(0, 0, "ID"); 60 | personsTable.setText(0, 1, "NAME"); 61 | personsTable.setText(0, 2, "DATE OF BIRTH"); 62 | personsTable.getRowFormatter().addStyleName(0, 63 | "tableHeader"); 64 | } 65 | 66 | for (Person p : persons) { 67 | int rowNum = personsTable.getRowCount(); 68 | personsTable.setText(rowNum, 0, 69 | String.valueOf(p.getId())); 70 | personsTable.setText(rowNum, 1, p.getName()); 71 | personsTable.setText(rowNum, 2, 72 | String.valueOf(p.getDateOfBirth())); 73 | } 74 | } 75 | 76 | @Override 77 | public void onFailure(Method method, Throwable exception) { 78 | Window.alert("Error while loading persons! Cause: " 79 | + exception.getMessage()); 80 | } 81 | }); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /restgwt/src/main/java/net/javaforge/gwt/rest/client/remote/rest/PersonResourceAsync.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.gwt.rest.client.remote.rest; 2 | 3 | import com.google.gwt.core.client.GWT; 4 | import net.javaforge.gwt.rest.shared.domain.Person; 5 | import org.fusesource.restygwt.client.MethodCallback; 6 | import org.fusesource.restygwt.client.Resource; 7 | import org.fusesource.restygwt.client.RestService; 8 | import org.fusesource.restygwt.client.RestServiceProxy; 9 | 10 | import javax.ws.rs.GET; 11 | import java.util.List; 12 | 13 | public interface PersonResourceAsync extends RestService { 14 | 15 | @GET 16 | void getPersons(MethodCallback> callback); 17 | 18 | /** 19 | * Utility class to get the instance of the Rest Service 20 | */ 21 | public static final class Util { 22 | 23 | private static PersonResourceAsync instance; 24 | 25 | public static final PersonResourceAsync get() { 26 | if (instance == null) { 27 | instance = GWT.create(PersonResourceAsync.class); 28 | ((RestServiceProxy) instance).setResource(new Resource( 29 | "rest/person")); 30 | } 31 | return instance; 32 | } 33 | 34 | private Util() { 35 | // Utility class should not be instantiated 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /restgwt/src/main/java/net/javaforge/gwt/rest/server/remote/rest/PersonResource.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.gwt.rest.server.remote.rest; 2 | 3 | import net.javaforge.gwt.rest.shared.domain.Person; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.ws.rs.GET; 8 | import javax.ws.rs.Path; 9 | import javax.ws.rs.Produces; 10 | import javax.ws.rs.core.MediaType; 11 | import java.util.ArrayList; 12 | import java.util.Date; 13 | import java.util.List; 14 | 15 | @Path("/person") 16 | public class PersonResource { 17 | 18 | private static final Logger logger = LoggerFactory 19 | .getLogger(PersonResource.class); 20 | 21 | private static int counter = 1; 22 | 23 | @GET 24 | @Produces(MediaType.APPLICATION_JSON) 25 | public List getPersons() { 26 | 27 | List persons = new ArrayList(); 28 | for (int i = 0; i < 5; i++) { 29 | persons.add(new Person(counter, "name-" + counter, new Date())); 30 | counter++; 31 | } 32 | 33 | logger.info("Returning {} persons...", persons.size()); 34 | 35 | return persons; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /restgwt/src/main/java/net/javaforge/gwt/rest/shared/domain/Person.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.gwt.rest.shared.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class Person { 6 | 7 | private int id; 8 | 9 | private String name; 10 | 11 | private Date dateOfBirth; 12 | 13 | public Person() { 14 | } 15 | 16 | public Person(int id, String name, Date dateOfBirth) { 17 | this.id = id; 18 | this.name = name; 19 | this.dateOfBirth = dateOfBirth; 20 | } 21 | 22 | // getter / setter goes here 23 | 24 | public int getId() { 25 | return this.id; 26 | } 27 | 28 | public String getName() { 29 | return this.name; 30 | } 31 | 32 | public Date getDateOfBirth() { 33 | return this.dateOfBirth; 34 | } 35 | 36 | public void setId(int id) { 37 | this.id = id; 38 | } 39 | 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | 44 | public void setDateOfBirth(Date dateOfBirth) { 45 | this.dateOfBirth = dateOfBirth; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "Person [id=" + this.id + ", name=" + this.name 51 | + ", dateOfBirth=" + this.dateOfBirth + "]"; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /restgwt/src/main/resources/net/javaforge/gwt/rest/App.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /restgwt/src/main/webapp/App.css: -------------------------------------------------------------------------------- 1 | *, body { 2 | font-size: 10px; 3 | font-family: sans-serif; 4 | } 5 | 6 | .tableHeader { 7 | background-color: #CCCCCC; 8 | color: #FFFFFF; 9 | } -------------------------------------------------------------------------------- /restgwt/src/main/webapp/App.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Web Application Starter Project 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /restgwt/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | jersey-rest 10 | com.sun.jersey.spi.container.servlet.ServletContainer 11 | 12 | com.sun.jersey.config.property.packages 13 | net.javaforge.gwt.rest.server.remote.rest 14 | 15 | 16 | com.sun.jersey.api.json.POJOMappingFeature 17 | true 18 | 19 | 1 20 | 21 | 22 | 23 | jersey-rest 24 | /rest/* 25 | 26 | 27 | 28 | 29 | App.html 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /springaop-custom-interceptor/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | net.javaforge.blog 6 | springaop-custom-interceptor 7 | 1.0-SNAPSHOT 8 | jar 9 | 10 | springaop-custom-interceptor 11 | http://maven.apache.org 12 | 13 | 14 | 15 | UTF-8 16 | 17 | 18 | 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-compiler-plugin 23 | 2.5.1 24 | 25 | 1.6 26 | 1.6 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.springframework 35 | spring-aop 36 | 3.2.6.RELEASE 37 | 38 | 39 | commons-logging 40 | commons-logging 41 | 42 | 43 | 44 | 45 | org.springframework 46 | spring-context 47 | 3.2.6.RELEASE 48 | 49 | 50 | commons-logging 51 | commons-logging 52 | 53 | 54 | 55 | 56 | org.slf4j 57 | slf4j-api 58 | 1.6.6 59 | 60 | 61 | org.slf4j 62 | jcl-over-slf4j 63 | 1.6.6 64 | 65 | 66 | cglib 67 | cglib-nodep 68 | 3.1 69 | 70 | 71 | org.slf4j 72 | slf4j-simple 73 | 1.6.6 74 | test 75 | 76 | 77 | junit 78 | junit 79 | 4.11 80 | test 81 | 82 | 83 | org.springframework 84 | spring-test 85 | 3.2.6.RELEASE 86 | test 87 | 88 | 89 | commons-logging 90 | commons-logging 91 | 92 | 93 | 94 | 95 | org.mockito 96 | mockito-all 97 | 1.9.5 98 | test 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /springaop-custom-interceptor/src/main/java/net/javaforge/blog/spring/Bean.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.spring; 2 | 3 | 4 | import net.javaforge.blog.spring.aop.ProfileExecution; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class Bean { 11 | 12 | private static final Logger log = LoggerFactory.getLogger(Bean.class); 13 | 14 | 15 | @ProfileExecution 16 | public void foo() { 17 | log.info("Executing method 'foo'."); 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /springaop-custom-interceptor/src/main/java/net/javaforge/blog/spring/aop/ProfileExecution.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.spring.aop; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author Maxim Kalina 7 | * @version $Id$ 8 | */ 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Target(ElementType.METHOD) 11 | @Inherited 12 | @Documented 13 | public @interface ProfileExecution { 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springaop-custom-interceptor/src/main/java/net/javaforge/blog/spring/aop/ProfilingAdvisor.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.spring.aop; 2 | 3 | import org.aopalliance.aop.Advice; 4 | import org.springframework.aop.Pointcut; 5 | import org.springframework.aop.support.AbstractPointcutAdvisor; 6 | import org.springframework.aop.support.StaticMethodMatcherPointcut; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.lang.reflect.Method; 11 | 12 | /** 13 | * @author Maxim Kalina 14 | * @version $Id$ 15 | */ 16 | @Component 17 | public class ProfilingAdvisor extends AbstractPointcutAdvisor { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | private final StaticMethodMatcherPointcut pointcut = new 22 | StaticMethodMatcherPointcut() { 23 | @Override 24 | public boolean matches(Method method, Class targetClass) { 25 | return method.isAnnotationPresent(ProfileExecution.class); 26 | } 27 | }; 28 | 29 | @Autowired 30 | private ProfilingMethodInterceptor interceptor; 31 | 32 | @Override 33 | public Pointcut getPointcut() { 34 | return this.pointcut; 35 | } 36 | 37 | @Override 38 | public Advice getAdvice() { 39 | return this.interceptor; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /springaop-custom-interceptor/src/main/java/net/javaforge/blog/spring/aop/ProfilingMethodInterceptor.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.spring.aop; 2 | 3 | import org.aopalliance.intercept.MethodInterceptor; 4 | import org.aopalliance.intercept.MethodInvocation; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.util.StopWatch; 9 | 10 | /** 11 | * @author Maxim Kalina 12 | * @version $Id$ 13 | */ 14 | @Component 15 | public class ProfilingMethodInterceptor implements MethodInterceptor { 16 | 17 | private static final Logger log = LoggerFactory.getLogger(ProfilingMethodInterceptor.class); 18 | 19 | @Override 20 | public Object invoke(MethodInvocation invocation) throws Throwable { 21 | final StopWatch stopWatch = new StopWatch(invocation.getMethod().toGenericString()); 22 | stopWatch.start("invocation.proceed()"); 23 | 24 | try { 25 | log.info(">>>>>>> START METHOD {} <<<<<<<<<", invocation.getMethod().toGenericString()); 26 | return invocation.proceed(); 27 | } finally { 28 | stopWatch.stop(); 29 | log.info(stopWatch.prettyPrint()); 30 | log.info(">>>>>>> END METHOD {} <<<<<<<<<", invocation.getMethod().toGenericString()); 31 | } 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /springaop-custom-interceptor/src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /springaop-custom-interceptor/src/test/java/net/javaforge/blog/spring/ProfilingTest.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.spring; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.test.context.ContextConfiguration; 7 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 8 | 9 | @RunWith(SpringJUnit4ClassRunner.class) 10 | @ContextConfiguration("classpath:applicationContext.xml") 11 | public class ProfilingTest { 12 | 13 | @Autowired 14 | private Bean bean; 15 | 16 | @Test 17 | public void testProfiling() { 18 | bean.foo(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /sshd-daemon-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | net.javaforge.blog 6 | sshd-daemon-demo 7 | 1.0.0-SNAPSHOT 8 | jar 9 | 10 | sshd-daemon-demo 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 2.5.1 23 | 24 | 1.6 25 | 1.6 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.apache.sshd 35 | sshd-core 36 | 0.9.0 37 | 38 | 39 | jline 40 | jline 41 | 2.11 42 | 43 | 44 | 45 | 46 | org.slf4j 47 | slf4j-simple 48 | 1.6.6 49 | 50 | 51 | 52 | junit 53 | junit 54 | 3.8.1 55 | test 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /sshd-daemon-demo/src/main/java/net/javaforge/blog/sshd/App.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.sshd; 2 | 3 | import org.apache.sshd.SshServer; 4 | import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; 5 | 6 | public class App { 7 | public static void main(String[] args) throws Throwable { 8 | SshServer sshd = SshServer.setUpDefaultServer(); 9 | sshd.setPort(5222); 10 | sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("hostkey.ser")); 11 | sshd.setPasswordAuthenticator(new InAppPasswordAuthenticator()); 12 | sshd.setShellFactory(new InAppShellFactory()); 13 | sshd.start(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sshd-daemon-demo/src/main/java/net/javaforge/blog/sshd/InAppPasswordAuthenticator.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.sshd; 2 | 3 | import org.apache.sshd.server.PasswordAuthenticator; 4 | import org.apache.sshd.server.session.ServerSession; 5 | 6 | /** 7 | * @author Maxim Kalina 8 | * @version $Id$ 9 | */ 10 | public class InAppPasswordAuthenticator implements PasswordAuthenticator { 11 | @Override 12 | public boolean authenticate(String username, String password, ServerSession session) { 13 | return username != null && username.equals(password); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sshd-daemon-demo/src/main/java/net/javaforge/blog/sshd/InAppShellFactory.java: -------------------------------------------------------------------------------- 1 | package net.javaforge.blog.sshd; 2 | 3 | import jline.console.ConsoleReader; 4 | import jline.console.completer.StringsCompleter; 5 | import org.apache.sshd.common.Factory; 6 | import org.apache.sshd.server.Command; 7 | import org.apache.sshd.server.Environment; 8 | import org.apache.sshd.server.ExitCallback; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import java.io.*; 13 | 14 | /** 15 | * @author Maxim Kalina 16 | * @version $Id$ 17 | */ 18 | public class InAppShellFactory implements Factory { 19 | 20 | public Command create() { 21 | return new InAppShell(); 22 | } 23 | 24 | private static class InAppShell implements Command, Runnable { 25 | 26 | private static final Logger log = LoggerFactory.getLogger(InAppShell.class); 27 | 28 | public static final boolean IS_MAC_OSX = System.getProperty("os.name").startsWith("Mac OS X"); 29 | 30 | private static final String SHELL_THREAD_NAME = "InAppShell"; 31 | private static final String SHELL_PROMPT = "app> "; 32 | private static final String SHELL_CMD_QUIT = "quit"; 33 | private static final String SHELL_CMD_EXIT = "exit"; 34 | private static final String SHELL_CMD_VERSION = "version"; 35 | private static final String SHELL_CMD_HELP = "help"; 36 | 37 | private InputStream in; 38 | private OutputStream out; 39 | private OutputStream err; 40 | private ExitCallback callback; 41 | private Environment environment; 42 | private Thread thread; 43 | private ConsoleReader reader; 44 | private PrintWriter writer; 45 | 46 | public InputStream getIn() { 47 | return in; 48 | } 49 | 50 | public OutputStream getOut() { 51 | return out; 52 | } 53 | 54 | public OutputStream getErr() { 55 | return err; 56 | } 57 | 58 | public Environment getEnvironment() { 59 | return environment; 60 | } 61 | 62 | public void setInputStream(InputStream in) { 63 | this.in = in; 64 | } 65 | 66 | public void setOutputStream(OutputStream out) { 67 | this.out = out; 68 | } 69 | 70 | public void setErrorStream(OutputStream err) { 71 | this.err = err; 72 | } 73 | 74 | public void setExitCallback(ExitCallback callback) { 75 | this.callback = callback; 76 | } 77 | 78 | public void start(Environment env) throws IOException { 79 | environment = env; 80 | thread = new Thread(this, SHELL_THREAD_NAME); 81 | thread.start(); 82 | } 83 | 84 | public void destroy() { 85 | if (reader != null) 86 | reader.shutdown(); 87 | thread.interrupt(); 88 | } 89 | 90 | /** 91 | * {@inheritDoc} 92 | */ 93 | @Override 94 | public void run() { 95 | try { 96 | 97 | 98 | reader = new ConsoleReader(in, new FilterOutputStream(out) { 99 | @Override 100 | public void write(final int i) throws IOException { 101 | super.write(i); 102 | 103 | // workaround for MacOSX!! reset line after CR.. 104 | if (IS_MAC_OSX && i == ConsoleReader.CR.toCharArray()[0]) { 105 | super.write(ConsoleReader.RESET_LINE); 106 | } 107 | } 108 | }); 109 | reader.setPrompt(SHELL_PROMPT); 110 | reader.addCompleter(new StringsCompleter(SHELL_CMD_QUIT, 111 | SHELL_CMD_EXIT, SHELL_CMD_VERSION, SHELL_CMD_HELP)); 112 | writer = new PrintWriter(reader.getOutput()); 113 | 114 | // output welcome banner on ssh session startup 115 | writer.println("****************************************************"); 116 | writer.println("* Welcome to Application Shell. *"); 117 | writer.println("****************************************************"); 118 | writer.flush(); 119 | 120 | String line; 121 | while ((line = reader.readLine()) != null) { 122 | handleUserInput(line.trim()); 123 | } 124 | 125 | } catch (InterruptedIOException e) { 126 | // Ignore 127 | } catch (Exception e) { 128 | log.error("Error executing InAppShell...", e); 129 | } finally { 130 | callback.onExit(0); 131 | } 132 | } 133 | 134 | private void handleUserInput(String line) throws InterruptedIOException { 135 | 136 | if (line.equalsIgnoreCase(SHELL_CMD_QUIT) 137 | || line.equalsIgnoreCase(SHELL_CMD_EXIT)) 138 | throw new InterruptedIOException(); 139 | 140 | String response = null; 141 | if (line.equalsIgnoreCase(SHELL_CMD_VERSION)) 142 | response = "InApp version 1.0.0"; 143 | else if (line.equalsIgnoreCase(SHELL_CMD_HELP)) 144 | response = "Help is not implemented yet..."; 145 | else 146 | response = "======> \"" + line + "\""; 147 | 148 | writer.println(response); 149 | writer.flush(); 150 | } 151 | } 152 | } -------------------------------------------------------------------------------- /sshd-daemon-demo/sshd-daemon-demo.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 39 | 198 | 211 | 212 | 213 | 214 | --------------------------------------------------------------------------------