
package com.smartgwt.client.docs;

/**
 * <h3>Reify for Developers</h3>
 * <b>What is Reify?</b>
 *  <p>
 * Reify is a web-based visual application builder that enables non-developers to build Smart GWT 
 *  screens, and even build complete applications.
 *  <P>
 * Reify creates standard Smart GWT Component XML screen definitions, DataSource definitions, and 
 *  XML event handler and workflow declarations. 
 * This means you can take a Reify application and extend it with standard Smart GWT coding
 * techniques.  
 *  <P>
 * You can also use multiple Reify projects as part of a single, larger application. This approach
 * - 
 * called <i>hybrid development</i> - lets non-programmers build the simpler parts of your
 * application 
 *  in a visual tool, while developers build other parts with code, as usual.
 *  <P>
 *  <b>Why Hybrid Development works</b>
 *  <P>
 * Normally, it's not realistic for a developer to maintain or extend code that was generated by a
 * 
 *  visual tool. However, Reify's <i>hybrid development</i> model actually works, because:
 *  <dl>
 *  <dt>1. Reify generates 100% declarative XML, never procedural code</dt>
 * <dd>No programmer would ever want to try to maintain or extend code generated by a visual tool.
 * 
 * Reify is different: everything Reify produces is concise XML declarations, and is just standard
 * 
 *  use of the Smart GWT framework. You can look up any setting you see used in a Reify-generated 
 * screen in the Smart GWT documentation. We've also put a great deal of effort into ensuring that
 * 
 *  the XML declarations produced by Reify are concise and self-explanatory.</dd>
 *  <dt>2. DataSources define a clean and clear boundary between UI and backend concerns</dt>
 * <dd>Within the Reify visual tool, designers work with <i>MockDataSources</i>, which have the
 * same 
 * fields and behavior as real DataSources, but use sample data. Because Smart GWT's UI components
 * 
 * know nothing about the actual implementation of a DataSource's operations, the MockDataSources
 * can 
 *  be replaced with real DataSources, and the screen works the same.</dd>
 *  <dt>3. Reify screens are encapsulated and reusable</dt>
 * <dd>Screens have no global variables, and all the behavior of the screen is confined to within 
 *  the screen. So you don't need to worry about naive designers breaking some other part of your 
 * application: DataSource operations are the only global interaction. And, you can create the
 * same 
 * screen more than once, even concurrently, so designers can build things like a tab that appears
 * 
 *  multiple times with different data.</dd>
 *  </dl>
 *  <b>The Hybrid Development workflow</b>
 *  <P>
 * With <i>hybrid development</i>, non-programmers (such as product managers) use Reify to design 
 * screens, sometimes enlisting the help of developers for more complex tasks, and then developers
 * 
 *  incorporate those screens into a standard Smart GWT application.
 *  <P>
 *  If you have an existing Smart GWT application, you can quickly get your existing DataSources 
 * into Reify so that designers start out with DataSource definitions that already match the
 * production 
 * design (see "<b>Uploading existing DataSources to Reify</b>" below - we provide a special
 * tool).
 *  <P>
 *  While designers work on the UI, developers can get to work immediately on backend concerns, 
 *  or on screens that are too complex to build visually. As designers begin to produce screens, 
 *  if those screens will require some hand-coded aspects, developers can work 
 *  on those aspects <i>in parallel</i>, even while the designer is further refining or extending 
 *  the screen within Reify (see the sections on <i>adding custom behavior</i> below).
 *  <P>
 *  <i>Hybrid development</i> creates a far more efficient development process:
 *  <ul>
 *  <li>Simpler screens and simpler applications don't require developers to build</li>
 *  <li>Far less room for miscommunication, since designers build interactive screens instead of 
 *  throw-away mockups</li>
 * <li>End users can try out the design without needing developers to build the whole application 
 *  first (a.k.a. User Acceptance Testing)</li>
 * <li>Applications are easier to maintain, since the simpler screens remain editable in the Reify
 * 
 *  visual tool</li>
 *  </ul>
 *  <P>
 *  In addition, because it's always possible to export your Reify projects and keep going in an 
 *  IDE environment, you can start any kind of project with Reify - you don't have to limit your 
 *  use of Reify to only projects that can be built completely in a visual tool.
 *  <P>
 *  <b>Loading Reify Projects</b>
 *  <P>
 *  An Reify project consists of:
 *  <ol>
 * <li>a project file (projectName.proj.xml) which lists all the screens and DataSources involved 
 *  in the project</li>
 *  <li>one or more screen files (screenName.ui.xml) which have 
 *  {@link com.smartgwt.client.docs.ComponentXML Component XML} screen definitions</li>
 * <li>one or more DataSource files (dataSourceId.ds.xml) which have {@link
 * com.smartgwt.client.data.DataSource} definitions</li>
 *  </ol>
 *  <P>
 * You can load a Reify project from Reify.com (or from a {@link
 * com.smartgwt.client.docs.ReifyOnSite Reify Onsite} server) 
 *  with just a call to Reify.loadProject(), like so:
 *  
 *  
 *  <pre>
 *  <code>
 *  LoadProjectSettings settings = new LoadProjectSettings();  
 *  settings.setUserName(<i>reifyUserName</i>);  
 *  settings.setPassword(<i>reifyPassword</i>); 
 *  Reify.loadProject(<i>projectName</i>, new LoadProjectCallback() {  
 *     &#64;Override
 *     public void execute(Project project, Project[] projects, RPCResponse rpcResponse) {
 *         Canvas screen = project.createScreen((project.getScreenNames()[0]));  
 *         // screen is now a Canvas - not drawn - put it somewhere via addMember() / addChild() / whatever 
 *     }
 *  }, settings); 
 *  </code>
 *  </pre>
 *  
 *  This is the quickest way to try out a Reify screen when you are working in a standard 
 *  Smart GWT project, and if you later download the Reify project and add its files to your 
 *  Smart GWT project, you just change from <code>Reify.loadProject()
 *  </code> to <code>RPCManager.loadProject()</code> 
 *  (although you can also deploy with live loading of projects - see <b>Live Editable 
 *  Applications</b> below).
 *  <P>
 *  If the Smart GWT page where you load your project already has DataSources with the same 
 *  IDs as the MockDataSources defined in the Reify project, the DataSources in the page will 
 * be used instead, and the MockDataSources ignored. In this way, you can easily test out a Reify 
 *  screen working with real DataSources, even as it continues to be refined in the Reify visual 
 *  tool, using equivalent MockDataSources. You can turn on 
 * {@link com.smartgwt.client.rpc.LoadProjectSettings#getVerifyDataSources automatic verification}
 * of loaded DataSources, 
 * to make sure they match your local DataSources (no fields have been removed, for example) - see
 * the
 * <a href='https://www.smartclient.com/smartclient-latest/showcase/?id=verifyingScreensReify'
 * target='_blank'>Verifying Screens</a>
 *  sample for an example of doing this.
 *  <P>
 * If the Reify screen has MockDataSources that don't exist in the local page, those will be used,
 * 
 * where they will behave like {@link com.smartgwt.client.data.DataSource#getClientOnly clientOnly
 * DataSources}, mimicking a 
 *  real DataSource but using using sample data embedded in the MockDataSource file itself, with 
 *  all changes lost on page reload.
 *  </P>
 *  If you don't want to use live loading, you can alternatively:
 *  <P>
 *  <ol>
 *  <li>Use Project &gt; Export menu in the Reify UI to obtain a .zip of your project's files</li>
 * <li>Use special {@link com.smartgwt.client.docs.ReifyMaven Maven commands} to pull project
 * files live from a Reify server 
 *  into any Maven-managed project</li>
 *  </ol>
 *  <P>
 *  Note finally that if your project has multiple screens and you only want to load part of it, 
 * you can of course use the {@link com.smartgwt.client.rpc.RPCManager#loadScreen screen}
 * (.ui.xml) and DataSource (.ds.xml) 
 *  files from your project on their own; they do not depend on the project file (.proj.xml).
 *  <P>
 *  <b>Deploying a Reify Project Separately</b>
 *  <P>
 *  If you've built a complete application in Reify, and for whatever reason you have decided to 
 *  deploy on your own, just change the project to use SQL storage:
 *  <ol>
 *  <li>For all of your DataSources, change the outer tag to &lt;SQLDataSource&gt;</li>
 * <li>use the {@link com.smartgwt.client.docs.AdminConsole Admin Console} tool to configure a
 * connection to a SQL database, 
 *  and create tables from the DataSources</li>
 *  <li>load the project via adding a &lt;script&gt; tag that uses the 
 * {@link com.smartgwt.client.rpc.RPCManager#loadProject ProjectLoaderServlet} to load your
 * project
 *  </li>
 *  </ol>
 *  <p>
 *  .. and your project is now ready to deploy.
 *  <p>
 *  <b>Hybrid development style: mixing Reify projects and hand-coding</b>
 *  <p>
 * It's easy to use Reify for just the simpler parts of a complex application. For example, the
 * start 
 * screen of a complex application might need to be hand-coded, but from there, other screens
 * might be 
 * Reify projects or hand-coded, in any mix. Even a hand-coded screen might use a Reify project
 * for a 
 *  pop-up dialog or wizard. All that's necessary to do this is to
 * {@link com.smartgwt.client.rpc.RPCManager#loadProject load the Reify project} into your
 * existing application, and use
 * {@link com.smartgwt.client.rpc.RPCManager#createScreen RPCManager.createScreen()} at the point
 * where you want to introduce Reify-created screens.
 *  <p>
 * Remember that while your Reify project is built and tested as a full-screen application,
 * there's no 
 * requirement that it takes over the screen when embedded into a larger application. For example,
 * say 
 * you have a hand-coded application where the main screen consists of a {@link
 * com.smartgwt.client.widgets.layout.SplitPane} with a tree 
 * on the left, which controls what components are shown in the {@link
 * com.smartgwt.client.widgets.layout.SplitPane#getDetailPane detailPane} 
 * on the right. You've loaded a Reify project with a screen called "leadDetails". If you wanted
 * to 
 *  place a Reify-created screen in <i>just the right pane</i>, you can just do this:
 *  
 *  
 *  <pre>
 *      <i>mySplitPane</i>.setDetailPane(RPCManager.createScreen("leadDetails"));
 *  </pre>
 *  
 * Similarly, imagine you are building a modal window in Reify, such as a wizard or a pop-up
 * dialog. 
 * There's no reason for the <code>Window</code> component itself to appear in the Reify project,
 * since 
 *  you can just do this:
 *  
 *  
 *  <pre>    
 *     Window myWindow = new Window();
 *     myWindow.addItem(RPCManager.createScreen("<i>reifyScreenName</i>"));
 *     ... other properties ...
 *  </pre>
 *  
 * Leaving the <code>Window</code> component out of the Reify project gives you a little more room
 * 
 * to work in the editor, and may be a more natural split in your application. Alternatively, you
 * may 
 * want the <code>Window</code> in the Reify project so that previewers see something closer to
 * the 
 *  actual appearance.  
 *  <p>
 * Either approach is fine; the key point is that in the Hybrid Development approach, you can
 * place 
 * the boundary between your Reify screens and your custom code <i>anywhere you want</i>. You can
 * use a 
 * Reify screen for the contents of a window, or a tab, or even just the <i>lower half</i> of a
 * tab, 
 * if there is a hand-coded component that needs to appear up top. This makes it possible to use
 * Reify 
 *  for a much greater proportion of your application than may at first be obvious.
 *  <p>
 *  <b>Hybrid Development: adding custom behavior while leaving Reify resources unchanged</b>
 *  <p>
 * If you leave the files retrieved from Reify unchanged, you can continue to modify them visually
 * 
 * and collaboratively in the Reify tool, and pull updates into your project at any time.  Smart
 * GWT 
 * and Reify give you multiple ways to add custom behavior to a Reify screen without changing the 
 *  original screen XML:
 *  <ol>
 *  <li> you can add event handlers to components in a loaded screen
 *  
 *  
 *  <pre>    
 *  ListGrid mainGrid = (ListGrid)RPCManager.createScreen("<i>screenName</i>");
 *  mainGrid.addRecordClickHandler(new RecordClickHandler() {
 *      &#64;Override
 *      public void onRecordClick(RecordClickEvent event) {
 *          myApp.loadRelatedImages(event.getRecord());
 *      }
 *  });
 *  </pre>
 *  
 *  <p>
 *  
 *  <p>
 *  </li>
 * <li> you can swap in custom subclasses for standard components. For example, say you have a
 * custom 
 * subclass of <code>ListGrid</code> that you want to use everywhere in your application - you can
 * use 
 * {@link com.smartgwt.client.rpc.CreateScreenSettings#getClassSubstitutions
 * CreateScreenSettings.classSubstitutions} to do that:
 *  
 *  
 *  <p><pre>
 *  CreateScreenSettings settings = new CreateScreenSettings();
 *  settings.setClassSubstitutions(new HashMap() {{ put("ListGrid", "MyCustomListGrid"); }});
 *  Canvas screen = RPCManager.createScreen("<i>screenName</i>", settings);
 *  </pre>
 *  
 * .. alternatively, you can use {@link
 * com.smartgwt.client.rpc.CreateScreenSettings#getComponentSubstitutions
 * CreateScreenSettings.componentSubstitutions} to change the 
 *  classes used for individual components by the component's ID:
 *  
 *  
 *  <p><pre>
 *  CreateScreenSettings settings = new CreateScreenSettings();
 *  settings.setComponentSubstitutions(new HashMap() {{ put("mainGrid", myCustomListGrid); }});
 *  Canvas screen = RPCManager.createScreen("<i>screenName</i>", settings);
 *  </pre>
 *  
 *  </li>
 * <li> you can also inject components into the loaded screen, such as a custom component you've
 * written
 *  
 *  
 *  <p><pre>
 *  Canvas screen = RPCManager.createScreen("<i>screenName</i>");
 *  Layout mainLayout = (Layout)screen.getByLocalId("mainLayout");
 *  mainLayout.addMember(<i>customDisplayComponent</i>);
 *  </pre>
 *  
 *  </li>
 *  </ol>
 *  <p>
 * Using the above techniques, you can keep large portions of even a complex application in
 * declarative, 
 * Reify-editable files. This makes it much easier to make changes, and collaborate and iterate on
 * 
 *  possible designs.
 *  <p>
 * You can easily verify whether resources loaded from Reify have been changed to be incompatible 
 * with your custom logic - just use {@link
 * com.smartgwt.client.rpc.LoadProjectSettings#getVerifyComponents
 * LoadProjectSettings.verifyComponents} to declare the 
 * local IDs and types of the components you expect to be present in the screen, and a very clear 
 *  error will be reported if someone changes a screen in an incompatible fashion.  
 * See <a href='https://www.smartclient.com/smartclient-latest/showcase/?id=verifyingScreensReify'
 * target='_blank'>Verifying Screens</a>
 *  sample for an example of doing this.
 *  
 *  <p>
 *  <b>Uploading existing DataSources to Reify</b>
 *  <p>
 *  If you have existing DataSources in hand-coded applications, the quickest way to get
 *  them into Reify is to go to the Admin or Developer Console and do a Reify format export
 * from the {@link com.smartgwt.client.docs.DataSourcesTab DataSources tab}.  First open a section
 * for the DataSource
 *  and then set the export format picker to "Reify DataSource upload format".  Finally,
 *  within Reify, you can create a new DataSource by importing that XML in the DS Wizard.
 *  <p>
 *  You can also export multiple DataSources at once by clicking on the "Reify Export"
 *  button at the top of the DataSource tab in the DataSource List section header.  This
 *  special syntax consists of multiple DataSources each in "Reify format" XML.  If you need
 *  a programmatic solution, you can generate the same output with the
 * {@link com.smartgwt.client.tools.Reify#getMockDS Reify.getMockDS()} and {@link
 * com.smartgwt.client.tools.Reify#showMockDS Reify.showMockDS()} APIs, which allow you to provide
 *   criteria to get a specific set of sample data, in case that's important.
 *  <p>
 *  </pre>
 *  <p>
 *  If you give the DataSource you create in Reify the same ID as the real DataSource in
 *  your project, then when the Reify project is exported and added to an existing
 *  hand-coded project, the real DataSource will automatically take the place of the
 *  MockDataSource you create in Reify.
 *  <p>
 *  Note that Reify does not offer direct upload of existing .ds.xml files, because of the
 *  security implications of features such as
 * {@link com.smartgwt.client.data.OperationBinding#getCustomSQL &lt;customSQL&gt;} and {@link
 * com.smartgwt.client.docs.ServerScript Server\n Scripting}. Even aside from security concerns,
 * an existing .ds.xml can have dependencies
 * on other parts of your environment, such as custom {@link com.smartgwt.client.data.SimpleType
 * SimpleTypes},
 *  validators that invoke server Java code, or custom tags.
 *  <p>
 *  When you export to Reify-format XML and import as a MockDataSource, Reify automatically
 *  determines field types, including distinguishing between "time", "date", and "datetime"
 *  fields, as well as between "int" and "float" fields, so the MockDataSource is a perfect
 *  stand-in for your real DataSource for design purposes.
 * {@link com.smartgwt.client.util.MockDSExportSettings#getValidatorMode Standard validators} are
 * included in the
 *  exported field definitions by default.
 *  <p>
 *  Consider trimming the sample data down to 50-100 rows before creating the
 *  MockDataSource.  Any additional data won't do anything other than slightly slow down the
 *  tool, as sample data in Reify is stored inside the .ds.xml file and not in a SQL
 *  database or other production-capable data store.  If you export in Reify format from the
 *  DataSources tab, the logic there automatically chooses a low data volume and
 *  intelligently selects records so as to preserve relations.  For further details, seen
 * {@link com.smartgwt.client.tools.Reify#getMockDS Reify.getMockDS()}, the API on which the
 * DataSources tab's "Reify Export" button
 *  is built.
 *  <p>
 *  <b>Providing initial data to Reify screens</b>
 *  <p>
 *  Because Reify-created portions of your application use the same DataSources as the rest of 
 *  your application, they already have access to the same data. However, typically there is some 
 * context that the screen needs to do its job, such as the ID of the record the screen is
 * intended 
 *  to display or edit.
 *  <p>
 * It's always possible to simply reach into the Reify screen after you've created it, and
 * populate 
 * components with the necessary data. For example, if you create a Reify screen for editing an
 * Order 
 *  and its OrderItems, you could do something like this:
 *  <p>
 *  
 *  
 *  <pre>
 *   Canvas myScreen = RPCManager.createScreen("reifyScreenName");
 *   myScreen.getByLocalId("headerLabel").setContents("Order #" + orderId);
 *   Criteria criteria = new Criteria();
 *   criteria.addCriteria("orderId", orderId);
 *   ((DynamicForm)myScreen.getByLocalId("orderForm")).fetchData(criteria);
 *   ((ListGrid)myScreen.getByLocalId("orderItemsGrid")).fetchData(criteria);
 *  </pre>
 *  
 *  <p>
 *  This works, but has some drawbacks:
 *  <ul>
 *  <li>it creates dependencies on specific component IDs within the screen</li>
 *  <li>the screen can't easily be tested on its own - it needs the surrounding application 
 *  to perform a full test</li>
 * <li>if additional components are added to the screen that also consume the same data, more code
 * 
 *  may need to be added to populate those components</li>
 *  </ul>
 *  <P>
 * Instead, a Reify screen can define <i>screen inputs</i>, which are data values that are
 * expected to be 
 *  provided from outside of the screen.  When a screen has such inputs, you provide them via 
 *  {@link com.smartgwt.client.widgets.Canvas#getDataContext dataContext}, like so:
 *  <P>
 *  
 *  
 *  <pre>
 *   CreateScreenSettings globals = new CreateScreenSettings();
 *   DataContext dataContext = new DataContext();
 *   dataContext.addMapping("Order", orderRecord);
 *   globals.setDataContext(dataContext);
 *   Canvas myScreen = RPCManager.createScreen("reifyScreenName", globals);
 *  </pre>
 *  
 *  <p>
 *  This approach addresses all of the potential issues above, creating a clean & clear boundary
 *  between the Reify screen and the surrounding application.
 *  <p>
 * Within the Reify tool, screen inputs are stored as {@link
 * com.smartgwt.client.widgets.Canvas#getTestDataContext Canvas.testDataContext}. The
 *  designer selects DataSources the screen depends on, which provides the schema, and can
 *  also provide test values. This allows designers to define and test declarative logic
 *  (formulas, visibility rules, workflows, etc.) based on the expected inputs, even when
 *  testing the screen in isolation. At runtime, when the surrounding application provides a
 * {@link com.smartgwt.client.widgets.Canvas#getDataContext Canvas.dataContext}, it replaces the
 * <code>testDataContext</code> entirely.
 *  <p>
 * <code>dataContext</code> doesn't have to be limited to just DataSource records; in addition to 
 * required data, a Reify screen may have <i>settings</i> that are allowed.  For example, there
 * might be 
 * a setting for whether the screen allows editing, or allows editing of specific fields.  A Reify
 * 
 *  screen can just declare such settings as a DataSource, and set it as a screen input, and then 
 *  code using the screen can pass settings via dataContext as well, for example:
 *  <p>
 *  
 *  
 *  <pre>
 *   CreateScreenSettings globals = new CreateScreenSettings();
 *   DataContext dataContext = new DataContext();
 *   dataContext.addMapping("Order", orderRecord);
 *   dataContext.setAttribute("orderScreenConfiguration", 
 *           new HashMap() {{
 *               put("allowEditing", true);
 *               put("allowShipDateChanges", false);
 *           }} );
 *   globals.setDataContext(dataContext);
 *   Canvas myScreen = RPCManager.createScreen("reifyScreenName", globals);
 *  </pre>
 *  
 *  Here, possible settings for the screen have been captured as a DataSource called 
 *  <code>orderScreenConfiguration</code> (any name can be used).
 *  <p>
 * Note that in this particular example, whether certain types of editing are allowed is
 * controlled via 
 * external configuration, however, Reify screens can be dynamic in lots of ways: role-based
 * access to 
 * specific operations or fields, mobile adaptation, or even data-driven behavior such as not
 * allowing 
 * editing of an order that already has <code>status:"shipped"</code>.  Because of this, external 
 * configuration via <code>dataContext</code> is unusual, and you should carefully consider
 * whether 
 * it is really necessary, as compared to just using the standard Reify environment to control
 * screen 
 *  behavior.
 *  <p>
 *  To see Screen Inputs and <code>dataContext</code> in action, take a look at the 
 * <a href='https://www.smartclient.com/smartclient-latest/showcase/?id=screenInputsReify'
 * target='_blank'>Screen Inputs</a> 
 *  sample.
 *  <p>
 * Another pattern, called <i>shuttle DataSources</i>, can also be used to pass data to Reify
 * screens - 
 *  see the discussion towards the end of this document.
 *  <p>
 *  <b>Detecting that a Reify screen is done</b>
 *  <p>
 * For many if not most scenarios of embedding Reify screens in a larger application, the user
 * simply 
 * completes a task on the Reify-created screen and then navigates away, and may navigate back
 * later 
 * and complete more tasks, so nothing special needs to be done.  However, sometimes you need to
 * know 
 * when a user has completed interacting with a Reify-created screen (such as a wizard), so that
 * the 
 *  containing application code can take the next step.
 *  <p>
 *  There are a few simple techniques for doing this:
 *  <ul> 
 * <li> watch for an event on some object in the Reify screen - for example, wait for the click
 * event 
 *  on a "Done" button </li>
 * <li> watch for Reify screen to hide itself, if that's what it does on completion. You can do
 * this by
 *  
 *   adding a VisibilityChangedHandler 
 *  </li>
 *  <li> watch for a successful DataSource operation by
 *  
 *   adding a DataSourceDataChangedHandler 
 *  </li>
 * <li> have the Reify screen write to a <code>clientOnly</code> DataSource when it completes.
 * This is 
 * the same as the technique described above for providing initial data to a Reify screen, but in 
 * reverse. This is also useful if the Reify screen needs to pass data back to the main
 * application, 
 * and you'd prefer not to retrieve that data by simply interrogating components in the Reify
 * screen</li>
 *  </ul>
 *  <p>
 *  <b>Live Editable Applications</b>
 *  <P>
 *  If, in your deployed application, you use <code>Reify.loadProject()</code> 
 *  calls to load parts of 
 * your application live from Reify.com or a {@link com.smartgwt.client.docs.ReifyOnSite Reify
 * OnSite server}, that means that people can 
 * use Reify to <i>edit the live application</i>.  This is extremely powerful, as it allows you to
 * instantly 
 * respond to rapidly changing requirements (such as needing to add additional validation to a
 * field).  
 * However, it's obviously also possible to <i>break the live application</i> this way, so use
 * with caution.
 *  <P>
 *  SmartGWT provides tooling to
 * detect potential mistakes with {@link
 * com.smartgwt.client.rpc.LoadProjectSettings#getVerifyDataSources DataSources}
 * and {@link com.smartgwt.client.rpc.LoadProjectSettings#getVerifyComponents Components} on the
 * client at
 *  runtime, and at build-time through Maven goals, Ant tasks, or a Java CLI.
 *  For best results, Isomorphic recommends using both approaches.
 *  <p>
 *  By default, both
 * <a href='http://github.smartclient.com/isc-maven-plugin/reify-import-mojo.html'
 * target='_blank'>Maven</a>
 *  and 
 * <a
 * href='http://github.smartclient.com/isc-maven-plugin/apidocs/com/isomorphic/maven/mojo/reify/ImportTask.html'
 * target='_blank'>Ant</a>
 *  import utilities automatically check for common discrepancies on import, but this step 
 *  may also be run independently at any time using
 * <a href='http://github.smartclient.com/isc-maven-plugin/reify-validate-mojo.html'
 * target='_blank'>reify-validate</a>
 *  goal or
 * <a
 * href='http://github.smartclient.com/isc-maven-plugin/apidocs/com/isomorphic/maven/mojo/reify/ImportTask.html'
 * target='_blank'>ValidateTask</a>
 *  tasks, respectively.  For Maven, that could be as simple as something like this:
 *  <p>
 *  <pre>
 *  &lt;plugin&gt;
 *      &lt;groupId&gt;com.isomorphic&lt;/groupId&gt;
 *      &lt;artifactId&gt;isc-maven-plugin&lt;/artifactId&gt;
 *      &lt;version&gt;1.4.3&lt;/version&gt;
 *      &lt;configuration&gt;
 *        &lt;dataSourcesDir&gt;WEB-INF/ds/classic-models&lt;/dataSourcesDir&gt;
 *      &lt;/configuration&gt;
 *      &lt;dependencies&gt;
 *         &lt;dependency&gt;
 *             &lt;groupId&gt;com.isomorphic.extras&lt;/groupId&gt;
 *             &lt;artifactId&gt;isomorphic-m2pluginextras&lt;/artifactId&gt;
 *             &lt;version&gt;\${smartgwt.version}&lt;/version&gt;
 *         &lt;/dependency&gt;       
 *    &lt;/dependencies&gt;
 *  &lt;/plugin&gt; 
 *  
 *  mvn com.isomorphic:isc-maven-plugin:1.4.3:reify-validate
 *  </pre>
 *  and for Ant:
 *  <pre>
 *  &lt;target name="reify-validate" depends="reify-tasklibs"&gt;
 *      
 *      &lt;taskdef name="reify-validate"
 *               classname="com.isomorphic.maven.mojo.reify.ValidateTask"
 *               classpathref="reify.classpath"/&gt;
 *      &lt;reify-validate datasourcesDir="WEB-INF/ds/classic-models" 
 *                      smartclientRuntimeDir="\${basedir}/war/isomorphic" /&gt;
 *  &lt;/target&gt;   
 *  
 *  ant reify-validate
 *  </pre>
 *  <p>
 *  If, for any reason, one wanted access to the same feature outside of either Ant or Maven 
 *  environments, a Java class is provided for invocation from command line, scripts, etc.
 *  Note that in this case, however, the classpath would need manual setup to include the
 * isomorphic_m2pluginextras JAR and {@link com.smartgwt.client.docs.JavaModuleDependencies its
 * dependencies},
 *  and you'll need to provide the full path to your application resources.  Assuming the
 *  required JARs could all be found at tools/reify/lib, that might look something like 
 *  this:
 *  <pre>
 *  java -cp :tools/reify/lib/* com.isomorphic.tools.ReifyDataSourceValidator 
 *       -r /Users/you/dev/your-application/war/isomorphic
 *       -d /Users/you/dev/your-application/war/WEB-INF/ds/classic-models
 *       -m /Users/you/dev/your-application/war/WEB-INF/ds/mock
 *  </pre>
 *  <p>
 *  <b>Shuttle DataSources</b>
 *  <p>
 *  Reify <i>Screen Inputs</i> and <code>dataContext</code>, covered above, is the recommended 
 *  approach for providing data to a Reify screen.  However, another pattern is to use 
 *  <i>shuttle DataSources</i>.
 *  <p>
 *  Similar to the example given for <code>dataContext</code> above, where a special DataSource 
 *  is created to represent settings for the screen, a designer using Reify creates a DataSource 
 *  to represent the required input data for the screen, called a <i>shuttle</i> DataSource.  
 * That <i>shuttle DataSource</i> has exactly one record, which the Reify screen fetches at
 * startup 
 * (typically using the <i>drawn</i> event) and uses to populate components and/or configure the
 * screen.
 *  <p>
 *  You may find that a particular designer has built screens in this style rather than using 
 *  Screen Inputs and <code>dataContext</code>. If so, it's easy to provide data to such a 
 * screen: you just create a single-record, {@link
 * com.smartgwt.client.data.DataSource#getClientOnly clientOnly DataSource},
 * and provide the input data for the screen as that DataSource's {@link
 * com.smartgwt.client.data.DataSource#getCacheData DataSource.cacheData}.
 *  <p>
 *  For example, a Reify screen may be designed to load data related to a selected record from 
 *  the "customer" DataSource. In the Reify project, a MockDataSource called "selectedCustomer" 
 *  was created to represent the "customer" record whose data should be loaded. In your code 
 *  that needs to create the Reify screen, you've got a variable <code>currentCustomer</code> 
 *  that has the Record for the currently selected customer. To make the data available to 
 *  the Reify project, you can just do this:
 *  <p>
 *  
 *  
 *  <pre>
 *   DataSource selectedCustomer = new DataSource();
 *   selectedCustomer.setID("selectedCustomer");
 *   selectedCustomer.setInheritsFrom("customer");
 *   selectedCustomer.setClientOnly(true);
 *   selectedCustomer.setCacheData(<i>currentCustomer</i>);
 *   Canvas myScreen = RPCManager.createScreen("<i>reifyScreenName</i>");
 *   myScreen.draw();
 *  </pre>
 *  
 *  <p>
 *  Now the Reify screen can pull the data about the selected "customer" record from the 
 * "selectedCustomer" DataSource. The use of {@link
 * com.smartgwt.client.data.DataSource#getInheritsFrom DataSource.inheritsFrom} above helps to
 * avoid 
 *  duplicating field definitions, assuming the designer created their "selectedCustomer"
 *  DataSource as a field-compatible duplicate of the "customer" DataSource.
 *  <p>
 *  If the Reify screen is to be created multiple times for different customers, just use 
 *  DataSource.setCacheData() to update the data in the selectedCustomer client-only DataSource, 
 *  immediately before creating another instance of the screen
 *  <p>
 *  The <i>shuttle DataSource</i> pattern is a little worse than the use of <i>Screen Inputs</i>
 *  plus <code>dataContext</code> documented above:
 *  <ul>
 *  <li>you have a duplicate DataSource definition within Reify (selectedCustomer above)</li>
 *  <li>instead of having components automatically populated with data from the 
 *  <code>dataContext</code>, the Reify designer must do so manually, using a Workflow</li>
 *  </ul>
 *  <p>
 *  Therefore, you should generally use the Screen Inputs pattern rather than shuttle DataSource, 
 *  however, shuttle DataSources may still make sense in some edge cases.
 *  <p>
     * @see com.smartgwt.client.docs.ReifyCustomComponents
 */
public interface ReifyForDevelopers {
}
