
package com.smartgwt.client.docs;

/**
 * <h3>Integration with Spring</h3>
 * <b>Overview</b>
 *  <P>
 *  The Spring framework has many different parts, from integration with Object Relational
 *  Mapping (ORM) and transaction management systems, to a Model View Controller (MVC)
 *  architecture.
 *  <P>
 *  If you are building a new application from scratch and/or you are trying to 
 *  modernize the presentation layer of an existing application, most of Spring MVC is
 * inapplicable in the {@link com.smartgwt.client.docs.SmartArchitecture Smart GWT architecture}. 
 * Specifically,
 *  Smart GWT renders <b>all</b> HTML on the client, and the server is responsible only for
 *  retrieving data and enforcing business rules.  This means that Spring's ModelAndView and all
 *  functionality related to retrieving and rendering Views is unnecessary in Smart GWT.
 *  Smart GWT only needs the Model, and provides methods to deliver that Model to Smart GWT
 *  components (the server side method DSResponse.setData()).
 *  <P>
 *  However, Spring's DispatchServlet, Handler chain, and Controller architecture is applicable
 *  to Smart GWT.  See "Using Spring Controllers" below.
 *  <P>
 *  <b>Existing Spring Application</b>
 *  <P>
 * As discussed under the general {@link com.smartgwt.client.docs.ClientServerIntegration server
 * integration}
 *  topic, integrating Smart GWT into your application involves finding a way to provide data
 * that fulfills the {@link com.smartgwt.client.data.DSRequest DataSource requests} sent by Smart
 * GWT components.
 *  <P>
 *  There are 2 approaches for integrating Smart GWT into an existing Spring application:
 *  <ul>
 *  <li> <b>call Spring beans via Smart GWT DMI or custom DataSources</b>
 *  <span style="color:red">[Recommended]</span>: use Smart GWT Direct Method Invocation
 * (DMI) to map {@link com.smartgwt.client.data.DSRequest DataSource requests} to beans managed by
 * Spring, via
 * {@link com.smartgwt.client.docs.serverds.ServerObject#lookupStyle
 * ServerObject.lookupStyle}:"spring".   Return data to the browser by either simply
 *  returning it from your method, or via creating a DSResponse and calling DSResponse.setData()
 *  (server-side method).  Or, use a similar approach based on custom DataSource implementations
 * where the {@link com.smartgwt.client.docs.serverds.DataSource#serverConstructor
 * serverConstructor} is of the pattern 
 *  <b>"spring:{bean_name}"</b>
 *  <P>
 *  This is the easiest method and produces the best result.  A Collection of Java Beans, such
 *  as EJB or Hibernate-managed beans, can be directly returned to Smart GWT as the result of
 *  a DMI method, without the need to create an intervening
 * <a href='http://en.wikipedia.org/wiki/Data_transfer_object' target='_blank'>Data Transfer
 * Object</a> to express
 *  which fields should be delivered to the browser - instead, only the fields declared on the
 *  DataSource are returned to the browser (see
 * {@link com.smartgwt.client.data.DataSource#getDropExtraFields dropExtraFields}.  In this
 * integration scenario, the
 *  majority of the features of the Smart GWT Server framework still apply - see this
 *  {@link com.smartgwt.client.docs.FeaturesCustomPersistence overview}.
 *  <p>
 *  Note, there are special scoping considerations to bear in mind when using Spring-injected 
 * DataSources or DMIs - see {@link com.smartgwt.client.docs.ServerDataSourceImplementation this
 * discussion} of 
 *  caching and thread-safety issues.
 *  <P>
 *  <li> <b>configure Spring to return XML or JSON responses</b>: create variants
 *  on existing Spring workflows that use a different type of View in order to output XML or
 * JSON data instead of complete HTML pages.  The Smart GWT {@link
 * com.smartgwt.client.data.RestDataSource} provides a
 *  standard "REST" XML or JSON-based protocol you can implement, or you can adapt generic
 *  {@link com.smartgwt.client.data.DataSource DataSources} to existing formats.
 *  <P>
 *  In some Spring applications, all existing Spring workflows can be made callable by
 *  Smart GWT with a generic View class capable of serializing the Model to XML or JSON,
 *  combined with a Controller that always uses this View.  Consider the following Java
 *  anonymous class, which uses the Smart GWT JSTranslater class to dump the entire 
 *  Spring Model as a JSON response.
 *  <pre>
 *   new View() {
 *         public void render(Map model, HttpServletRequest request,
 *                            HttpServletResponse response) throws IOException {
 *                 final ServletOutputStream outputStream = response.getOutputStream();
 *                 response.setContentType("application/x-javascript");
 *                 outputStream.println(JSTranslater.get().toJS(model));
 *                 outputStream.close();
 *         }
 *         public String getContentType() {
 *                 return "application/x-javascript";
 *         }
 *   }
 *  </pre>
 *  <P>
 *  If you use this approach, you do not need to install the Smart GWT server, and can
 *  {@link iscInstall deploy} Smart GWT as simple web content (JS/media/HTML files).  If you
 *  are already familiar with how to generate XML from objects that typically appear in your
 *  Spring Models, this may be the easiest path.
 *  </ul>
 *  <P>
 *  <h3><b>Using Spring Controllers with Smart GWT DMI</b></h3>
 *  <P>
 *  You can create a Controller that invokes standard Smart GWT server request processing,
 *  including DMI, like so:
 *  <pre>
 *  public class SmartGWTRPCController extends AbstractController
 *  {
 *      public ModelAndView handleRequest(HttpServletRequest request, 
 *                                        HttpServletResponse response)
 *          throws Exception
 *      {
 *          // invoke Smart GWT server standard request processing
 *          com.isomorphic.rpc.RPCManager.processRequest(request, response);
 *          return null; // avoid default rendering
 *      }
 *  }
 *  </pre>
 *  This lets you use Spring's DispatchServlet, Handler chain and Controller architecture as a
 *  pre- and post-processing model wrapped around Smart GWT DMI.
 *  <p>
 *  <h3><b>Using Spring Transactions with Smart GWT DMI</b></h3>
 *  <p>
 *  You can make DMI's participate in Spring's transaction management scheme by setting the 
 * {@link com.smartgwt.client.data.DataSource#getUseSpringTransaction useSpringTransaction} flag
 * on your DataSources or 
 *  {@link com.smartgwt.client.data.OperationBinding}s.  This makes your DMI method(s) 
 *  transactional, and ensures that any DSRequests and Spring DAO operations executed within 
 *  that DMI use the same Spring-managed transaction.  See the documentation for 
 *  <code>useSpringTransaction</code> for more details.
 *  <p>
 *  In Power Edition and above, Smart GWT Server has its own transaction management system.
 *  This allows you to send {@link com.smartgwt.client.rpc.RPCManager#startQueue queues} of 
 * {@link com.smartgwt.client.data.DSRequest DSRequest}s to the server, and the entire queue will
 * be treated as a 
 *  single database transaction.  This is <b>not</b> the same thing as Spring transaction 
 *  integration: Smart GWT's built-in transaction management works across an entire queue of
 *  DSRequests, whereas Spring transactions are specific to a Java method that has been marked 
 * <code>&#x0040;Transactional</code> - the transaction starts and ends when the method starts and
 * 
 *  ends.
 *  <p>
 * It is possible to have an entire Smart GWT queue - including any
 * <code>&#x0040;Transactional</code>
 *  DMIs that contain both Spring DAO operations and DSRequests - use the same Spring-managed 
 *  transaction.  To do this:<ul>
 * <li>Create a new Spring service bean with a <code>&#x0040;Transactional</code> method like this
 *  (note, the isolation level can vary as you please, but the propagation type must be REQUIRED
 *  to enable proper sharing of the transaction):<pre>
 *     &#x0040;Transactional(isolation=Isolation.READ_COMMITTED, propagation=Propagation.REQUIRED)
 *     public class MyServiceBean {
 *  
 *         // invoke Smart GWT server standard request processing
 *         public void processQueue(RPCManager rpc) throws Exception {
 *             rpc.processRPCTransaction();
 *         }
 *     }</pre></li>
 *  <li><b>Either:</b> Subclass the <code>com.isomorphic.servlet.IDACall</code> servlet and 
 *  override its <code>processRPCTransaction</code> method to inject the service bean you just
 *  created and invoke its transactional method.  You will also have to change your 
 *  <code>web.xml</code> file to point at this new servlet rather than <code>IDACall</code></li>
 *  <li><b>Or:</b> Use a Spring Controller, as described in the section <b>Using Spring 
 *  Controllers with Smart GWT DMI</b>, above.  Just follow the instructions for using a 
 *  Spring Controller, but have your <code>handleRequest()</code> implementation inject your
 *  service bean and invoke its transactional method, as described for the <code>IDACall</code>
 *  subclass approach</li>
 *  </ul>
 *  Whether you choose the IDACall or Spring Controller approach, the important thing is that 
 *  the call to <code>RPCManager.processRPCTransaction()</code> takes place from within a 
 *  <code>&#x0040;Transactional</code> method of a Spring service bean.  This will place the 
 *  processing of the entire Smart GWT queue inside the transaction that is created by Spring
 *  to service that transactional method.
 *  <p>
 *  <h3><b>Using Spring DataSources with Smart GWT SQLDataSource</b></h3>
 *  <p>
 * Smartclient {@link com.smartgwt.client.docs.SqlDataSource SQL DataSources} may be configured to
 * obtain JDBC
 *  connections from the <code>javax.sql.DataSource</code> implementation provided by
 *  Spring context. Search for <code>sql.MyDatabase.interface.type</code> in
 * {@link com.smartgwt.client.docs.SqlSettings SQL settings} overview for the configuration
 * details.
 *  <p>
 *  <h3><b>Spring Compatibility</b></h3>
 *  <a href='https://spring.io/projects/spring-framework#learn' target='_blank'>Spring</a> &
 * <a href='https://hibernate.org/' target='_blank'>Hibernate</a> have gone through reworks
 * recently in which backwards compatibility
 * was lost, creating complexity and difficult tradeoffs for consumers of these libraries, where
 * there may be conflicting
 * requirements to use different, incompatible versions of those frameworks. We have tried to do
 * the best we can in
 *  terms of supporting many possible combinations of versions, where feasible.
 *  <p>
 * The <a href='https://spring.io/projects/spring-framework#learn' target='_blank'>Spring</a> 5
 * framework
 *  integrated with Smart GWT is only compatible with
 *  <a href='https://www.oracle.com/java/technologies/downloads/' target='_blank'>Java</a> 8+,
 * so you can't use older version of Java together with {@link
 * com.smartgwt.client.docs.SpringIntegration Smart GWT's built-in Spring support},
 * such as the "spring:" DMI target. <b>If you have to use a Java version less than 8</b>, please
 * see the "Using Java
 *  version less than 8" section at the end of this document.
 *  <h4>Using Hibernate 3 or 4 with Spring 5</h4>
 *  <p>
 * The <a href='https://spring.io/projects/spring-framework#learn' target='_blank'>Spring</a> 5
 * ships with
 * <a href='https://hibernate.org/' target='_blank'>Hibernate</a> 5 support only, i.e. without
 * built-in Hibernate 3 and 4
 *  support it used to have.
 *  <p>
 * Smart GWT provides "bridges" that allow Spring 5 to be used with Hibernate 3 or 4.  To use this
 * combination,
 *  include either <code>isomorphic_spring_hibernate3.jar</code> for Hibernate 3 support or
 *  <code>isomorphic_spring_hibernate4.jar</code> for Hibernate 4 support.
 *  <p>
 * Smartclient bridge classes are based on Spring 4.3.26
 * <code>org.springframework.orm.hibernate3</code> and
 * <code>org.springframework.orm.hibernate4</code> packages and are placed in corresponding
 * packages:
 * <code>com.isomorphic.springhibernate3</code> and <code>com.isomorphic.springhibernate4</code>.
 * So, for example,
 * to configure managed Hibernate SessionFactory
 * <code><b>com.isomorphic.springhibernate3</b>.LocalSessionFactoryBean</code>
 * class should be used instead of
 * <code><s>org.springframework.orm.hibernate3</s>.LocalSessionFactoryBean</code> class:
 *  <pre>
 *  &lt;bean id="hbSpringSessionFactory"
 *        className="<b>com.isomorphic.springhibernate3</b>.LocalSessionFactoryBean"&gt;
 *      &lt;property name="configLocation" value="classpath:hibernate.cfg.xml"/&gt;
 *  &lt;/bean&gt;
 *  </pre>
 *  Other than that the usage is the same.
 *  <h4>Using Hibernate 5</h4>
 * Hibernate 5 is not yet supported by Smartclient, but it still may be used via custom DataSource
 * implementation, as
 * is demonstrated in <a href='https://www.smartclient.com/smartclient/showcase/?id=ormDataSource'
 * target='_blank'>ORM DataSource</a> and
 * <a href='https://www.smartclient.com/smartclient/showcase/?id=reusableORMDataSource'
 * target='_blank'>Resusable ORM DataSource</a>
 * Showcase samples. Note that in this case Smartclient built-in Hibernate support would be lost
 * and features like
 * data pagination, server-side sorting and filtering, server summaries etc would also have to be
 * implemented
 *  manually in custom DataSource if you need them.
 *  <p>
 *  <h4>Using Java version less than 8</h4>
 *  <p>
 *  With pre JDK8, you cannot use Spring 5 (according to
 * <a
 * href='https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-5.x#upgrading-to-version-50'
 * target='_blank'>Spring docs</a>),
 * so, you have to remove all Spring 5 related jars. Then, you could use Spring 4 or earlier, but
 * without any of our framework support for Spring
 *  which, as of release 13.0, requires Spring 5+ (older releases work with Spring 4).
 *  <p>
 * To remove Spring from the Smart GWT server all Spring JARs must be removed from your
 * WEB-INF/lib server directory:
 *  <ul>
 *  <li>spring-aop-5.3.9.jar
 *  <li>spring-beans-5.3.9.jar
 *  <li>spring-context-5.3.9.jar
 *  <li>spring-context-support-5.3.9.jar
 *  <li>spring-core-5.3.9.jar
 *  <li>spring-expression-5.3.9.jar
 *  <li>spring-jdbc-5.3.9.jar
 *  <li>spring-orm-5.3.9.jar
 *  <li>spring-tx-5.3.9.jar
 *  <li>spring-web-5.3.9.jar
 *  <li>spring-webmvc-5.3.9.jar
 *  <li>isomorphic_spring.jar
 *  <li>isomorphic_spring_hibernate3.jar
 *  <li>isomorphic_spring_hibernate4.jar</ul>
 *  <p>
 *  and Spring configuration must be removed from your WEB-INF/web.xml:
 *  <pre>
 *  &lt;!-- standard spring configuration --&gt;
 *  &lt;context-param&gt;
 *      &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
 *      &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
 *  &lt;/context-param&gt;
 *  &lt;listener&gt;
 *      &lt;listener-class&gt;com.isomorphic.spring.ContextLoaderListener&lt;/listener-class&gt;
 *  &lt;/listener&gt;</pre>
 */
public interface SpringIntegration {
}
