スタンドアロンRAPアプリケーション

すべての人に挨拶! これは私の最初の記事ですので、理解した上で帰してください。



RAPとOSGiを初めて目にしてから1年が経ちましたが、一見したところ、これらのテクノロジーに夢中になりました。 残念ながら、ウェブ上でも、ゼロからクールなもの(ハローワールドを除く)を作成できるRAPに関するドキュメントはほとんどありません。 最初に、もちろん、OSGiが何であるかを知る必要があります。 このトピックでは、ネットワークに関する情報で十分です。グーグルで検索できます。 この記事はRAPに関するものなので、読者はすでにOSGiバンドルの作成方法、それらのインストールおよび実行方法を知っていることが理解されます。



つまり、タスクは次のように設定されます。「RAPを使用してサイトのカスタムインターフェイスを作成します。」 EclipseでOSGiバンドルプロジェクトを作成する方法は、読者が知っていると思います。



だから。 RAPを使用するほとんどすべての例は、明らかに1つの原則に基づいています。ワークベンチ以外は使用しません。 間違いなく、ワークベンチは、表形式のデータを操作する必要があり、インターフェイスが非常に直感的で柔軟である必要がない場合、ビジネスアプリケーションで素晴らしいです。 ただし、タスクが「RAPを使用してサイトを作成する」ように聞こえる場合、ワークベンチは適切ではありません。



最初に、アプリケーションへのエントリポイントを作成する必要があります。 また、宣言型サービスを使用しません。 この場合、特にこの場合、DSは悪です。 私のアプリケーションには、アプリケーションがビューであるMVCがあり、ユースケースの概念もあることをすぐに言わなければなりません。 しかし、まずは単純化された道を進みます。



アプリケーションへのエントリポイントの抽象クラスを作成し、後でアプリケーションをアプリケーションから継承できるようにします。



abstract public class ApplicationEntryPoint implements EntryPoint { private ApplicationSession mSession; private ApplicationWindow mApplicationWindow; private ApplicationController mController; private String mDeferredUsecaseRun; public ApplicationEntryPoint(UseCaseRegister usecaseRegister) { mSession = new ApplicationSession(); } public ApplicationSession getSession() { return mSession; } protected Shell createMainShell( Display display ) { Shell shell = new Shell(display, SWT.NO_TRIM); shell.setMaximized(true); shell.setData(RWT.CUSTOM_VARIANT, "mainshell"); shell.setLayout(new FillLayout()); return shell; } protected void clearShell(Shell shell) { Control[] controls = shell.getChildren(); for (int i = 0; i < controls.length; i++) { if(controls[i] != null) { controls[i].dispose(); } } } }
      
      







このような単純化されたエントリポイントクラスを次に示します。 2つのメソッドに興味があります:createMainShell-Shellが作成します-SWTの観点では、これがメインアプリケーションウィンドウであり、私たちにとっては、これはブラウザーのページです。 clearShell-ページ、つまりメインアプリケーションウィンドウのすべてを単純に削除します。 他のコンテンツを表示する必要がある場合は、シェル内にあるすべてのものを破棄し、新しいデータで埋めます。



次に、ApplicationConfigを作成します。



 public class ApplicationConfig implements ApplicationConfiguration { public ApplicationConfig() {} public void configure( Application application ) { application.setOperationMode(OperationMode.SWT_COMPATIBILITY); application.addResource("/images/16/help2.png", new ResourceLoader() { @Override public InputStream getResourceAsStream(String arg0) throws IOException { return ApplicationConfig.class. GetClassLoader(). getResourceAsStream("/images/16/help2.png"); } }); Map<String, String> properties = new HashMap<String, String>(); properties.put( WebClient.FAVICON, "/images/16/help2.png" ); properties.put( WebClient.PAGE_TITLE, "Public area" ); application.addEntryPoint("/public", new PublicAreaEntryPointFactory(), properties); properties = new HashMap<String, String>(); properties.put( WebClient.PAGE_TITLE, "Main area" ); application.addEntryPoint("/main", new MainApplicationEntryPointFactory(), properties); } }
      
      







これは、異なるURIでアクセス可能な複数の領域を構成できることを意味します。この場合は、/ publicおよび/ mainです。 各領域には、独自のファビコンとページタイトルを設定できます。 RWTのアプリケーションはファクトリーを介して作成されますが、これは今から行います。



 abstract public class ApplicationEntryPointFactory implements EntryPointFactory { public ApplicationEntryPointFactory() {} public EntryPoint create() { return null; } }
      
      







これは抽象的なファクトリーであり、決して知らないので便利です。 その後、アプリケーション全体を再描画するよりもすぐに実行します。 私はそれが重宝したと言います。



アプリケーション全体で使用されるアプリケーションセッションクラスについては、ほとんど忘れていました。



 final public class ApplicationSession { private PersistentManager mPersistent; private HttpSession mHttpSession; private String mLogin = ""; private Boolean mLoggedIn = false; private Locale mLocale = null; private User mUser; private Logger mLogger; public ApplicationSession() { mLocale = new Locale("ru", "RU"); mHttpSession = RWT.getUISession().getHttpSession(); mPersistent = new PersistentManager("mo"); /* *      . */ if (mHttpSession.getAttribute("login") != null) mLogin = (String) mHttpSession.getAttribute("login"); if (mHttpSession.getAttribute("user") != null) mUser = (User) mHttpSession.getAttribute("user"); mLogger = LoggerFactory.getLogger(ApplicationSession.class); } final public void login(User user, String login) { mLogin = login; mPersistent.setUser(user); mHttpSession.setAttribute("login", mLogin); mHttpSession.setAttribute("user", user); logger().debug("   {}", mLogin); } final public Logger logger() { return mLogger; } final public void setUser(User user) { mUser = user; mHttpSession.setAttribute("user", user); } final public User getUser() { return mUser; } final public PersistentManager persistent() { return mPersistent; } final public String getId() { return mHttpSession.getId(); } final public Locale getLocale() { return mLocale; } final public void setLanguage(String language) { if (language.toUpperCase().equals("RUSSIAN") || language.toUpperCase().equals("RU")) { mLocale = new Locale("ru", "RU"); } else { mLocale = new Locale("en", "EN"); } } }
      
      







ご覧のとおり、セッションでは可能なすべてを保存します。 ORMとHTTPセッションへのリンク、ユーザーオブジェクト、ユーザーのロケールとロガーがあります...一般に、アプリケーションの任意のポイント内で個人的に必要なものはすべてセッションに保存できます。 他のアプリケーションバンドルも含め、どこでも利用できます。



それでは、抽象EntryPointを実装します。



 /** *       . *       -   *     . */ public class MainApplicationEntryPointFactory extends ApplicationEntryPointFactory { public MainApplicationEntryPointFactory() { super(); } @Override public EntryPoint create() { MainApplicationEntryPoint mainApp = new MainApplicationEntryPoint(getUsecaseRegister()); return mainApp; } } /** *     ,    . *            *    URI,    . */ public class MainApplicationEntryPoint extends ApplicationEntryPoint { private Shell mShell; private CommonController mLoginController; private ApplicationController mCtrl; public MainApplicationEntryPoint() { super(); } @Override public int createUI() { Display display = new Display(); mShell = createMainShell( display ); //    try { if (getSession().getUser() != null) { //      //   . mCtrl = new MainApplicationController(getSession(), mShell); mCtrl.init(); } else { mCtrl = new PublicAreaController(getSession(), mShell); mCtrl.init(); } catch (Exception ex) { MessageDialog.openError(mShell, "!", ex.getMessage()); } //  ,      , //      . mShell.open(); //   while( !mShell.isDisposed() ) { if( !display.readAndDispatch() ) { display.sleep(); } } display.dispose(); return 0; } }
      
      







MVCがあることは既に書いているので、メインウィンドウ内のすべては適切なコントローラーを使用して作成されます。 パブリックドメインおよびアプリケーションの場合-それぞれ独自のコントローラー。 しかし、これはアプリケーション内ですでに機能しているものです。



一般に、シェルは同じコンポジットであり、コントロールや他のコンポジットをパックして使用できます。 何も作成しないと、空のシェルが作成されます。 それを扱う原理は、SWTに関する文献から引き出すことができます。 しかし、重要なことは、これは特定のURIで利用可能なアプリケーションになります。



さらに重要なことは、RWTワークベンチが提供するアーキテクチャに縛られなくなったことです。 ただし、リソース(たとえば、画像や外部JS)を使用するには、アプリケーションコンテキストを独自のものに変更する必要があります。 アプリケーションバンドルアクティベータの例を示します。



 public class Activator implements BundleActivator { public void start(BundleContext context) throws Exception { /* *    */ Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put("contextName", "app"); context.registerService(ApplicationConfiguration.class.getName(), new ApplicationConfig(), props); } public void stop(BundleContext context) throws Exception { } }
      
      







したがって、アプリケーションは、URIに参加するコンテキスト(/ app / publicまたは/ app / main)からアクセスできます。



PS。 私が引用したコードは、おおよその概念です。 愚かにそれをコピーし、それが動作することを期待-動作しません。 しかし、私がそのようなマニュアルを期限内に持っていれば、多くの時間を節約することが可能でしょう。



PPS お互いをより良く知りたい仲間のために。 RAPは以前のRich Ajaxプラットフォームであり、現在はリモートアプリケーションプラットフォームです。 RAPはEclipse Foundationの開発であり、シンブラウザクライアントを作成するためのJavaツールキットです。 このプロジェクトの有用性と機能に関する情報は、 eclipse.org / rapで入手できます。 主な機能の1つは、クライアント(ブラウザー)とサーバー間でデータを交換するためのオープンJSONベースのプロトコルです。 第二に、RWTはSWTインターフェースを再定義します。 つまり、SWTに当てはまるほとんどすべてを移植できます。これは、コードを効果的に再利用するための非常に大きな機会です。 理論的には、クラスパスに異なるクラスパスをサービスとして、クライアントをブラウザとして、またはデスクトップJavaアプリケーションとしてアタッチすることにより、同じアプリケーションを実行できます。 そして、これは最小限のコード変更です。 GWTはほぼ同様の機能を実行しますが、インターフェイスアーキテクチャを根本的に定義するわけではありません。



All Articles