Requires Platform version 44.2 or earlier;
Not supported in version 4.5 or higher - for 4.5 Web Service support see Data Services
Web service is a software system designed to support interoperable machine-to-machine interaction over a network. With Nexaweb platform, you can invoke webservices from both the server side and the client side. Nexaweb leverages two aspects of using web services:
- The web services that will be used are not known at a development time.
- Use of the web services needs to take place on the client side, but the client can not have connectivity to the web service itself due to security concerns and firewall/network issues.
You can find more information from the API document in the com.nexaweb.server.webservices and com.nexaweb.client.webservices package.
Two ways of using webserivces
Since a web service is usually running on a remote machine and the data types used by this web service might or might not be known in advance, you can access the web service data two ways:
1. Strongly typed usage, when you already know the data types at the compile time, you can call the methods directly in a strongly typed fashion at your compile time. For example, if the api.google.com provides a spelling suggestion web service and the service returns a GoogleSearchPort object as a service port, you can write code by directly calling:
_googlePort.doSpellingSuggestion("mykey", "pirimaid");
to get a spelling suggestion for the word.
2. Reflection usage, when you don't know or care much on the data type at the complie time, but you know the methods you want to call. Then for the same spelling suggestion service example, you would write:
Code Block | ||
---|---|---|
| ||
Class[] argsType = {String.class, String.class};
Method getSpellingMethod = getMethod("doSpellingSuggestion", argsType);
Object[] args = {"mykey", "pirimaid"}
String suggestion =
(String)getSpellingMethod .invoke(_googlePortObject, args); |
Configuring a web service through nexaweb-webservices.xml
Before configuring a webservice, you must know its Web Services Description Language (WSDL) document location. WSDL is an XML format for describing network services. A WSDL document is published by the web service provider. If you don't know how to get it, check with the web service provider. It's typically a url, like this one "http://api.google.com/GoogleSearch.wsdl". To make sure your WSDL url is correct, you should try to link to the url from your browser and, you should see an xml file.
The next step is to create a "nexaweb-webservices.xml" under your app's "WEB-INF" folder. You can add an entry like this:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?>
<web-services>
<web-service xmlns="http://nexaweb.com/webservices"
name="Google"
scratchDir="{0}/WEB-INF/WebServices/{1}"
wsdlUrl="http://api.google.com/GoogleSearch.wsdl"/>
</web-services> |
In this setting, you only need to modify two attributes for your particular web service:
- name - the name given to the web service and the key, in the java code, used to obtain the web service port from the WebServiceBroker
- wsdlUrl - the url to the WSDL document describing the service. This must be a fully qualified URL, valid as a java.net.URL object. Note that this attribute is mutually exclusive with the "wsdlPath" attribute, only one may be specified.
- scratchDir - you don't have to modify this one, it's a java.text.MessageFormat string that will be used as an argument to a java.io.File object. This will in turn be used as a directory for WebService source and class files. The arguments passed to this MessageFormat are: {0} - The ServletContext.getRealPath("/") {1} - The logical name of the web services
Another setting mentioned in the wsdlUrl is:
- wsdlPath - the path to the WSDL document describing the service This path is relative to your web application context. (e.g. - /WEB-INF/weather.wsdl). Keep in mind, it's mutually exclusive with wsdlUrl attribute.
Web service classes needed for compilation and runtime
Compilation time requirement.
When you choose the reflection usage, at the compilation time, you need only the classes required for developing a standard Nexaweb application. The web service data type will be discovered at runtime.
When you choose the strongly typed usage, you need a set of classes to compile your application. Nexaweb platform has automated most of the steps for you to generate these classes. However, you still need some manual steps to put them together.
The steps to pull out these classes are:
- Configure the "nexaweb-webservices.xml" and put the file under the WEB-INF folder.
- Deploy your application before writting any strongly-typed web service code.
- Launch your application, Nexaweb webservice servlet will automatically generate these classes in the folder you defined in the scratchDir.
- By default, when using the above defined nexaweb-webservices.xml, you will see a folder structure similar to the following (you need to have valid name and wsdlUrl first):
- The name you provide, in this case, 'Google' will be used as a folder name in which to put these classes.
WEB-INF/WebServices/Google/classes
/AxisClasses
/ClientClasses
/ServerClasses
The classes under the /ClientClasses are the ones required at the client compilation time. The classes under the /ServerClasses are the ones required at the server compilation time. Make sure these classes are in the classpath when you compile strongly-type usage codes using this web service.
Runtime requirement
The runtime requirements are the same for both the reflection usage and the strongly-typed usage. By default, everytime you launch an application with a valid nexaweb-webservices.xml, these classes will be generated once, and you don't need to explicitly put them into the runtime classpath. This is different from compilation requirement where you need to have the classes and put them into the classpath first before compiling the code. This guarantees you will always get up-to-date proxy classes and the data types at the runtime.
In the above strongly-typed compilation requirements, we talked about
/ClientClasses
/ServerClasses
they are also required at runtime regardless of the usage. There is another folder
/AxisClasses
that is also required at runtime. This is where Nexaweb uses the Axis library to generate the proxy classes for the web services support.
The classes listed in /AxisClasses and its dependency, the Axis libary, will be reserved and only loaded by the Nexaweb private classloader at the runtime. If you need to use other Axis libraries, you do not need to worry about any incompatibility issues.
Examples
The following web service sample codes are almost the same and fit running on the client side or the server side usage. There are only two differences to be noted.
1. To get the WebServiceBroker, on the server side, you can call:
Code Block | ||||
---|---|---|---|---|
| ||||
//Get the broker through ServiceManager on the server side
WebServiceBroker broker = ServiceManager.getWebServiceBroker(); |
On the client side, you can call:
Code Block | ||||
---|---|---|---|---|
| ||||
//Get the broker through ClientSession on the client side
WebServiceBroker broker = clientSession.getWebServiceBroker(); |
2. When the code is running on the server side, you need to make an additional call to disover the web service.
Code Block | ||||
---|---|---|---|---|
| ||||
// Discovers the web service, writes the Java classes,
// compiles and loads the classes.
// This call is only available on the server side.
broker.createWebService( name, wsdlUrl ); |
Also, make sure the runtime required classes are generated in the appropriate client and server classpaths even if you don't have to configure them.
Strongly-type usage example
In strongly-type usage case, besides runtime requirement classes, make sure you compile your code with the client or server's compile time required classes in the compile paths.
Code Block | ||||
---|---|---|---|---|
| ||||
//Get the broker first based on client or server side code
String wsdlUrl = "http://api.google.com/GoogleSearch.wsdl"
String name="GoogleWebService";
// Server side only call
// broker.createWebService(name, wsdlUrl);
// This call retrieves the Port on which the web service's
// methods are available
GoogleSearchPort googlePort =
(GoogleSearchPort)broker.getServicePort(name);
String pyramid =
googlePort.doSpellingSuggestion("myKey", "piramid");
// 'piramid' is intentionally spelled wrong here |
In this example, the GoogleSearchPort is a strongly typed object, which is an instance of a class defined by the GoogleSearch service.
Reflection usage example
Code Block | ||||
---|---|---|---|---|
| ||||
//Get the broker first based on client or server side code
String wsdlUrl = "http://api.google.com/GoogleSearch.wsdl"
String name="GoogleWebService";
// Server side only call
// broker.createWebService(name, wsdlUrl);
// This call retrieves the Port on which the web
// service's methods are available
Object googlePort = broker.getServicePort(name);
// Now through reflection get the "doSpellingSuggestion" method
Method method = googlePort.getClass().getDeclaredMethod
("doSpellingSuggestion", new Class[]
{String.class, String.class} );
// Invoke the method using java reflection supplying
// your arguments
String pyramid = (String)method.invoke
( googlePort, new Object[]{"myKey", "piramid"}); |
Limitations
With the current framework, to compile the strongly-type application, a user still needs to manually start the application once and jar the classes in the /ClientClasses or /ServerClasses folder for future strongly-type code compilation. This will be addressed in the future release.
+
Plug-ins
Nexaweb Client プラグインアーキテクチャは、開発者が独自のタグや属性、XML シンタックスを実装できるよう設計されており、これによってNexaweb Java アプリケーション用Nexaweb Client の機能を拡張できます。通常、開発者は新しいUI コンポーネントを通じて機能を拡張しますが、論理演算やレイアウトペインなどのカスタムロジックを実装することも可能です。
Nexaweb Client での一般的な使用例の1 つとして、高度なチャート機能の使用が挙げられます。Nexaweb Client には組み込みのチャート機能が付属していますが、この機能は財務アプリケーションに見られるような高度なチャートの表示には不十分な場合があります。プラ グインアーキテクチャを使用すると、開発者はサードパーティのチャートコンポーネントを統合して独自のXML タグを定義し、フォーマット設定してそのチャートを表示することができます。その後このチャートを標準のXAL の内部に組み込むことができます。
例:
Code Block |
---|
<window>
<borderPane/>
<label text="A custom chart" borderPosition="north" />
<!-- a specialized chart created via the plug-in architecture -->
<financialChart title="Dow Jones by year" borderPosition="center" onSelect="myPage.jsp>
<xAxis start="1950" end="2005"/>
<yAxis start="0" y="5000"/>
<pointData points="1900,2000,2020 ... "/>
</financialChart>
</window> |
技術的な概要
最も基本的なレベルでは、プラグインはcom.nexaweb.client.tags.AbstractTagImpl を拡張するクラスであり、XML 要素に対する変更をリスンします。このような変更は、
com.nexaweb.xml.events.StructureChangeEventおよび
com.nexaweb.xml.events.AttributeChangeEventの形式で行われます。これらのクラスは、各タグ名にそれぞれが処理するクラスが含まれるため、タグハンドラと呼ばれます。また、これらのクラスは、XML と実装クラス(ピア) 間のブリッジを形成するため、ブリッジクラスとも呼ばれます。
AbstractTagImpl は、すべてのプラグインの基本クラスです。また、プラグインをタイプ別に簡単に作成できるように、多数のサブクラスが存在します。たとえば、ContainerBridge またはSwingBridge をサブクラスとして使用すれば、
java.awt.Component またはjavax.swing.JComponent に基づいたUI コンポーネントを作成できます。さらに、JComponent を使用して、独自のjava.awt.LayoutManager クラスを実装することもできます。
上記の例では、開発者は、ピアとして機能するサードパーティ製チャートコンポーネントをいくつか使っています。AbstractTagImpl を拡張するハンドラクラスは、ピアクラスでの変更に応答するだけでなく、XML での変更に基づいてこれらのピアを操作します。
AbstractTagImpl とこのサブクラスは、StructureChangeEvents とAttributeChangeEvents、関連するXML 要素を自動的にリスンします。属性が変更されたり、子タグの追加や削除が行われた際には、各サブクラスが適切な操作を実行します。同様にサブクラスは、ピ アオブジェクトへの変更をリスンしてイベントを発生させたり、変更に基づいてUI DOM (Document Object Model) を更新することができます。ブリッジクラスは、双方向のブリッジです。一方ではXML の変更をリスンしてピアに渡し、他方ではピアの変更をリスンしてイベントを発生させたり、変更に基づいてDOM を更新します。
このプラグインを目的のJVM で実行するには、注意が必要です。Swing に基づいて作成されたUI コンポーネントプラグインは、Swing と互換性のある(1.2+) JVM でしか実行できません。
JButton プラグインの開発
ここでは、JButton コンポーネントに<jButton> タグをマップする簡単なプラグインを開発します。<jButton> タグは、backGroundColor などの基本的な属性を認識します。また、<jButton> タグは"armed" という名前のブール型の属性を実装し、有効化された際にonCommand イベントを発生させます。
<jButton> タグの開発での最初の手順では、<jButton> タグにマップするタグハンドラを作成します。JButton はSwing に基づいたコンポーネントなので、クラスはSwingBridge を拡張します。パーサーは、初めて<jButton> タグを検出した際に、このJButtonBridge のインスタンスをインスタンス化し、これに対する初期化メソッドを呼び出します。これらのメソッドの1 つであるinit() が、順にcreateUiComponent() を呼び出します。目的のUI コンポーネントを作成するには、次のようにこのメソッドをオーバーライドする必要があります。
Code Block |
---|
public class JButtonBridge extends SwingBridge {
public void createUiComponent(){
setUiComponent(new JButton() );
}
} |
この時点で、ブリッジクラスがJButton コンポーネントを作成し、bgColor などの基本的な属性に自動的に応答します。また、このタグを"armed" 属性に応答させる必要があります。これには、onAttributeSet() をオーバーライドして、新しい属性を処理させます。
Code Block |
---|
public void attributeSet(AttributeChangeEvent e) throws AttributeConversionException {
String attributeName = e.getName();
String attributeValue = e.getNewValue();
//if the attribute is "armed" set it to true or false
if ("armed".equals(attributeName) ){
( (JButton)getUiComponent() ).getModel().setArmed(AttributeConverter.toBoolean(attributeValue));
}
//otherwise just fall through
else super.attributeSet(e);
} |
AttributeConverter は、文字列をブール型、Color、列挙型などのデータタイプに変換するメソッドを提供するユーティリティクラスです。attributeSet をオーバーライドしてAttributeConverter を使用すると、XML のエラーが通常の方法で報告されます。
<jButton> が属性の変更に応答できるようになったので、次は、JButton ActionListener が呼び出された際に<jButton> が"onCommand" イベントを報告するようにします。これには、ActionListener を実装して、自身をJButton のリスナとして追加します。こうしておけば、actionPerformed() が呼び出された際に、イベントの発生を処理するAbstractTagImpl からメソッドを呼び出すだけで済みます。JButtonBridge の最終的なコードは次のとおりです。最新の変更が強調表示されています。
Code Block |
---|
public class JButtonBridge extends SwingBridge implements ActionListener{
public void createUiComponent(){
JButton b = new JButton();
setUiComponent(b);
//listen for action events so we can report them
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
//call the method from AbstractTagImpl that reports the event
//fill in a ClientEvent object and calls the appropriate MCO/JSP/event handler
fireEvent("onCommand",null);
}
public void attributeSet(AttributeChangeEvent e) throws AttributeConversionException{
String attributeName = e.getName();
String attributeValue = e.getNewValue();
//if the attribute is "armed" set it to true or false
if ("armed".equals(attributeName) ){
( (JButton)getUiComponent() ).getModel().setArmed(AttributeConverter.toBoolean(attributeValue) );
}
//otherwise just fall through
else super.attributeSet(e);
}
} |
JButtonBridge が完了したので、次はJButtonBridge クラスによって<jButton> タグが定義、処理されるよう、マッピングを追加する必要があります。これには、適切なエントリでタグマッピングファイルを作成する必要があります。その 後、このファイルをクライアントコンフィギュレーション内のタグマッピングファイルのリストに追加します。タグマッピングファイル自体は、ハンドラクラス の名前がテキストとして記載された、単なるタグ名のリストです。このファイルをcustomTagMappings.xml と呼びます。
Code Block |
---|
<tag-mappings>
<jButton>JButtonBridge</jButton>
</tag-mappings> |
このファイルが作成されたら、nexaweb-client.xml にエントリーを追加しなくてはなりません。
Code Block |
---|
<client-tag-mapping>
<tag-map-file>customTagMappings.xml</tag-map-file>
</client-tag-mapping> |
Plug-in Architecture Class Survey
次の表は、plug-in関連クラスをリスト化し概要を説明しています。
Class | 説明 |
AbstractTagImpl | 全てのplug-inのベースクラス |
ContainerBridge | UI component plug-inのベースクラス。このクラスは全てのjava.awt.Componentsに適用する共通属性に対応している。 |
SwingBridge | Swing-based plug-ins のためのContainerBridge のサブクラス |
LayoutBridge | カスタムLayoutManager tagを作成するためのAbstractTagImplのサブクラス |
AttributeConverter | データtypeに属性値を変換し、エラーを統一し報告するユーティリティクラス |
Plug-in Class Lifecycle
新しいXALブロックが既存のUI DOMに加えられるとき :
1. ルートエレメントに関連したクラス名が検索される
2. クラスがロードされていなければ、ロードされる。
3. handler クラスの新しいインスタンスが作成される。
4. 現在の ClientSession で setSession() がハンドラから呼び出される。
5. HandlerはStructureChangeListener とAttributeChangeListener として XAL elementに追加される。
6. setElement() はXAL element で handler に呼び出される。
7. init() はhandler に呼び出される。
8. "onCreate" イベントはハンドラにより呼び出される。
このプロセスは全てのXAL ブロックで一回のみ行われます。そのブロックのroot elementは、それに設定された子および/または最初の属性を持っている可能性があります。AbstractTagImplは、これらの状況に対処す るため、init() に呼び出されることができる2つのメソッドを提供しています。"parseInitialChildren()" メソッドはこのパーシングプロセスを初期elementの全ての子に反復し行います。"parseInitialAttributes()" メソッドは、element作成後に設定されたかのように、onAttributeSet()で初期elementの属性をフィードします。加え、 ContainerBridgeは、その init() メソッドでデフォルトによりこれらのメソッドを呼び出します。
XAL blockがUI DOMから除外された場合 :
- unload() は root element に対し、handler に呼び出される。
- handler は StructureChangeListener とAttributeChangeListener として XAL element から除外される。
- handler は除外された root Element の各子エレメントのプロセスを再帰的に反復する afterChildRemoved() を呼び出します。
onChildRemoved()に優先するhandler classが存在する場合、再帰的更新が発生するようにafterChildRemoved()を呼び出さなくてはなりません。
Packaging Plug-Ins
プラグインはタグマッピングファイル、タグハンドラクラス、ピアクラスの3つのリソースで構成されています。我々の例では、JButton ピアクラスは全ての Swing の互換性のある JVM に含まれますが、時によりピアクラスが別の JAR ファイルに含まれます。
Tag-handling class とピアクラスは MCO と同じ展開ルールに従っていますが、タグマッピングファイルは、標準ファイルとして見なされます。一部の開発者は、タグマッピングファイルとクラスを組み 合わせ、JAR ファイルに入れるのが簡単だということがわかるかもしれません。例えば、JButtonBridge クラスとcustomTagMappings.xml は "jButtonPlugin.jar." と呼ばれるものの中に JAR ファイル化されています。その場合、nexweb-client.xml classpath を変更しその jar を含み、タグマッピングロケーションを変更し"classpath://" specifier. を使用します。nexaweb-client.xml のドキュメントの client classpath 調整についての詳細をご覧ください。
Code Block |
---|
<!-- classpath changed to include our plug-in jar file -->
<client-classpath>
<pre-loaded-in-applet-def>
<archive name="jButtonPlugin.jar"
path="/WEB-INF/client/lib/jButtonPlugin.jar"/>
</pre-loaded-in-applet-def>
</client-classpath>
<!-- load the tag mapping file from the classpath -->
<client-tag-mapping>
<tag-map-file>classpath://customTagMappings.xml</tag-map-file>
</client-tag-mapping> |
最後一つのパッケージオプションは、スタートアップで、そのプラグインにあったタグが初めて遭遇した時に、plug-in class をロードさせることです。スタートアップでロードされたクラスは Nexaweb のローディングアニメーションの最中にロードされますが、一方で、オンザフライでロードされた大規模 plug-in だと Nexaweb のアプリケーションが数秒フリーズしてしまいます。アプリケーションが、大規模 plug-in をコンスタントに、また頻繁に使用される場合、スタートアップの際ロードする方が良いです。これは、以下のように tag-mapping を修正することで可能です。
Code Block |
---|
<tag-mappings>
<jButton loadPolicy="onStartup">JButtonBridge</jButton>
</tag-mappings> |
Plugin Namespaceの定義
Namespaces は、タグ一式で定義することができます。以下の例は、Nexaweb Data Frameworkで、これはプラグイン アーキテクチャを使用し実装されます。このプラグインを定義するXMLは以下です。
Code Block |
---|
<tag-mappings namespace="http://openxal.org/core/data"
document="bindings">
<mapping class="com.nexaweb.plugin.data.bridge.BindingBridge"
name="binding"/>
</tag-mappings> |
ここではopenxal.org/core/data namespace のタグ "binding" を宣言しています。
組込みコンポーネントより優先される
プラグインは組込み XAL タグの振る舞いを置換えるために使用することができます。例えば、プラグインが <button> として定義されると、button の本来の振る舞いを置換えます。
Packaging and Distributing Nexaweb Application Plug-ins
Nexaweb アプリケーション用プラグインのパッケージ化と配布
Nexaweb 4.2.x で Nexaweb アプリケーションに使用するプラグインをパッケージ化して配布するには、次の作業を行う必要があります。
- プラグインのマニフェスト ファイルでプラグインに関する情報を指定する
- プラグインの JAR ファイルをアプリケーションの WEB-INF/client/plugins ディレクトリに配置する
プラグインのマニフェストファイルへのプラグイン情報の追加
アプリケーションに作成する各プラグインに関する情報を、プラグインのマニフェストファイル、plugin.xmlに追加する必要があります。Nexaweb では、プラグインのマニフェストを使用して、プラグインのコンテンツを決定します。
各プラグインの plugin.xml ファイルに次のセクションを追加します。
セクション | 説明 |
<plugin> </plugin> | このアプリケーションにインクルードする固有のプラグインを特定します。 開始タグには、ライフサイクルマネージャまたはプラグインの抽象 MCO を指定する、オプションの class 属性をインクルードできます。 |
<info> </info> | プラグイン スキーマとスタイルシートの場所など、プラグインに関する一般的な情報を指定します。 |
<tag-mappings> </tag-mappings> | プラグインがアプリケーションに追加するタグを定義し、複合タグの定義ファイルの場所と、アプリケーションがプラグインをロードする際に使用するポリシーを指定します。 |
次に、プラグインのマニフェストファイルのサンプルを示します。
Code Block |
---|
<plugin class="MyPlugins">
<info>
<provider-name>Nexaweb Technologies</provider-name>
<author>James</author>
<description>This plug-in automates automatic automation.</description>
<version>10.3.4</version>
<schema-location>schema/plugin.xsd</schema-location>
<stylesheet-location>stylesheet/stylesheet.xss</stylesheet-location>
</info>
<tag-mappings namespace="http://nexaweb.com/charts" document="nxml">
<mapping name="barChart" class="com.nexaweb.plugins.BarChart" icon="barChart.gif" loadPolicy="onStartup"/>
<mapping name="loginDialog" class="com.nexaweb.plugins.LoginDialog" icon="loginDialog.gif" definitionFile="ui/loginDialog.nxml"/>
</tag-mappings>
</plugin> |
次の表では、<info> セクションに含まれるタグについて説明します。
info タグ | 説明 |
<provider-name> </provider-name> | プラグインの作成者に関する情報を指定します。 |
<author> </author> | プラグインの作成者に関する情報を指定します。 |
<description> </description> | プラグインの目的または使用に関する情報を提供します。 |
<version> </version> | プラグインのバージョン番号を指定します。 |
<schema-location> </schema-location> | このプラグインのスキーマ ファイルの場所を特定します。 |
<stylesheet-location> </stylesheet-location> | このプラグインのスタイルシートの場所を特定します。デフォルトの配布先は、JAR ファイルが配置されているディレクトリ内の /stylesheet です。 |
次の表では、<tag-mapping> セクションに含まれるタグの属性について説明します。
tag-mapping タグの属性 | 説明 |
namespace | これらのタグマッピングが属する名前空間を指定します。 |
mapping name | アプリケーションに追加されるプラグインで使用されるタグ名を指定します。 |
マッピング名の属性
属性 | 説明 |
class | このタグが属するクラスを指定します。このクラスは、lib または classes フォルダ内に存在する場合があります。 |
icon | このタグに関連付けられている任意のイメージを指定します。イメージは、イメージフォルダに対して相対的な位置にあります。 |
loadpolicy | この属性を使用して、Nexaweb の起動時にこのプラグインを起動することを指定します。この属性の有効な値は onStartup のみです。この属性がタグマッピングに存在しない場合は、このタグが最初に検出されたときにプラグインが起動します。 |
definitionFile | 複合タグに含まれる複数の関数を定義するファイルの場所を指定します。 |
プラグインディレクトリの構造
Nexaweb Studio では、ビルドおよび配布に独自のディレクトリ構造を使用してプラグインが構成されます。
プラグインのビルドには、次の表に示すディレクトリ構造が使用されます。
ビルド用ディレクトリ | 含まれる内容 |
/source | Java ソースコード。 |
/dependencies | プラグインと一緒にパッケージ化されない依存関係で、実行時に存在する必要があります。 |
/dependencies/lib | JAR ファイル (例: jaxp.jar)。 |
/dependencies/plugins | このプラグインが依存する他のプラグイン (例: data-interfaces-plugin.jar)。 |
/PluginContent | Web アプリケーションの WebContent とほぼ同じです。Nexaweb では、このディレクトリのコンテンツは plugin.jar 構造のルートに配置されます。 |
/build | ビルドのステージング領域で、ビルド プロセスが終了すると削除される場合があります。 |
/dist | ビルドによって生成されるプラグイン JAR。 |
プラグインの配布には、次の表に示すディレクトリ構造が使用されます。
配布用ディレクトリ | 含まれる内容 |
/lib | プラグインが依存する JAR ファイル(クラスはクライアントにバインドされており、公に提供可能である必要があります)。 |
/images | イメージ。 |
/PLUGIN-INF/docs | プラグインドキュメントの場所。 |
/PLUGIN-INF/schema/plugin.xsd | プラグインのスキーマ ファイル。 |
/stylesheet/stylesheet.xss | プラグインのスタイルシート。 |
/plugin.xml | プラグインのマニフェスト ファイル。 |