Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[#1493] Done on i18n of docviewer

  • Loading branch information...
commit 576f9228aed8eaa7e493db7fa19369500868de3c 1 parent e06ec08
Takafumi Ikeda ikeike443 authored
Showing with 15,179 additions and 179 deletions.
  1. +82 −0 documentation/cheatsheets_ja/commandLine/ch25-CommandLinePlayCommand.textile
  2. +27 −0 documentation/cheatsheets_ja/controllers/ch01-ControllerActionSmartbinding.textile
  3. +27 −0 documentation/cheatsheets_ja/controllers/ch02-ControllerActionValidation.textile
  4. +27 −0 documentation/cheatsheets_ja/controllers/ch03-ControllerSessionManagement.textile
  5. +22 −0 documentation/cheatsheets_ja/controllers/ch04-ControllerActionRedirection.textile
  6. +12 −0 documentation/cheatsheets_ja/controllers/ch05-ControllerJobs.textile
  7. +18 −0 documentation/cheatsheets_ja/controllers/ch06-ControllerInterceptions.textile
  8. +15 −0 documentation/cheatsheets_ja/controllers/ch07-ControllerActionOthers.textile
  9. +64 −0 documentation/cheatsheets_ja/controllers/ch08-ControllerLibraries.textile
  10. +32 −0 documentation/cheatsheets_ja/model/ch14-ModelActionQueries.textile
  11. +16 −0 documentation/cheatsheets_ja/model/ch15-ModelBasics.textile
  12. +11 −0 documentation/cheatsheets_ja/model/ch16-ModelGenerators.textile
  13. +31 −0 documentation/cheatsheets_ja/model/ch17-ModelRelationalMapping.textile
  14. +21 −0 documentation/cheatsheets_ja/model/ch18-ModelCallbacks.textile
  15. +23 −0 documentation/cheatsheets_ja/model/ch19-ModelRelations.textile
  16. +12 −0 documentation/cheatsheets_ja/model/ch20-ModelJPAQueries.textile
  17. +20 −0 documentation/cheatsheets_ja/multiEnvironment/ch26-MultiEnvironment.textile
  18. +28 −0 documentation/cheatsheets_ja/templates/ch09-TemplateImplicitObjects.textile
  19. +31 −0 documentation/cheatsheets_ja/templates/ch10-TemplateTagGrammar.textile
  20. +52 −0 documentation/cheatsheets_ja/templates/ch11-TemplateStandardTags.textile
  21. +8 −0 documentation/cheatsheets_ja/templates/ch12-TemplateCustomTags.textile
  22. +77 −0 documentation/cheatsheets_ja/templates/ch13-TemplateGroovyExtension.textile
  23. +24 −0 documentation/cheatsheets_ja/tests/ch21-TestUnitTests.textile
  24. +16 −0 documentation/cheatsheets_ja/tests/ch22-TestFunctionalTests.textile
  25. +13 −0 documentation/cheatsheets_ja/tests/ch23-TestSeleniumTests.textile
  26. +9 −0 documentation/cheatsheets_ja/tests/ch24-TestDataloader.textile
  27. +123 −0 documentation/manual_ja/5things.textile
  28. +68 −0 documentation/manual_ja/ajax.textile
  29. +199 −0 documentation/manual_ja/asynchronous.textile
  30. +103 −0 documentation/manual_ja/cache.textile
  31. +916 −0 documentation/manual_ja/configuration.textile
  32. +809 −0 documentation/manual_ja/controllers.textile
  33. +314 −0 documentation/manual_ja/crud.textile
  34. +383 −0 documentation/manual_ja/dependency.textile
  35. +195 −0 documentation/manual_ja/deployment.textile
  36. +154 −0 documentation/manual_ja/emails.textile
  37. +301 −0 documentation/manual_ja/evolutions.textile
  38. +53 −0 documentation/manual_ja/faq.textile
  39. +328 −0 documentation/manual_ja/firstapp.textile
  40. +252 −0 documentation/manual_ja/guide1.textile
  41. +204 −0 documentation/manual_ja/guide10.textile
  42. +78 −0 documentation/manual_ja/guide11.textile
  43. +330 −0 documentation/manual_ja/guide12.textile
  44. +430 −0 documentation/manual_ja/guide2.textile
  45. +328 −0 documentation/manual_ja/guide3.textile
  46. +244 −0 documentation/manual_ja/guide4.textile
  47. +138 −0 documentation/manual_ja/guide5.textile
  48. +290 −0 documentation/manual_ja/guide6.textile
  49. +374 −0 documentation/manual_ja/guide7.textile
  50. +315 −0 documentation/manual_ja/guide8.textile
  51. +276 −0 documentation/manual_ja/guide9.textile
  52. +197 −0 documentation/manual_ja/home.textile
  53. +135 −0 documentation/manual_ja/i18n.textile
  54. +156 −0 documentation/manual_ja/ide.textile
  55. +52 −0 documentation/manual_ja/ids.textile
  56. +124 −0 documentation/manual_ja/index.textile
  57. +91 −0 documentation/manual_ja/install.textile
  58. +400 −0 documentation/manual_ja/javaextensions.textile
  59. +138 −0 documentation/manual_ja/jobs.textile
  60. +285 −0 documentation/manual_ja/jpa.textile
  61. +129 −0 documentation/manual_ja/lambdaj.textile
  62. +333 −0 documentation/manual_ja/libs.textile
  63. +49 −0 documentation/manual_ja/logs.textile
  64. +156 −0 documentation/manual_ja/main.textile
  65. +229 −0 documentation/manual_ja/model.textile
  66. +140 −0 documentation/manual_ja/modules.textile
  67. +122 −0 documentation/manual_ja/overview.textile
  68. +239 −0 documentation/manual_ja/production.textile
  69. +230 −0 documentation/manual_ja/releasenotes-1.0.1.textile
  70. +139 −0 documentation/manual_ja/releasenotes-1.0.2.textile
  71. +27 −0 documentation/manual_ja/releasenotes-1.0.3.textile
  72. +318 −0 documentation/manual_ja/releasenotes-1.1.textile
  73. +44 −0 documentation/manual_ja/releasenotes-1.2.4.textile
  74. +10 −0 documentation/manual_ja/releasenotes-1.2.5.textile
  75. +196 −0 documentation/manual_ja/releasenotes-1.2.textile
  76. +227 −0 documentation/manual_ja/releasenotes.textile
  77. +342 −0 documentation/manual_ja/routes.textile
  78. +45 −0 documentation/manual_ja/samples.textile
  79. +148 −0 documentation/manual_ja/secure.textile
  80. +96 −0 documentation/manual_ja/security.textile
  81. +557 −0 documentation/manual_ja/tags.textile
  82. +374 −0 documentation/manual_ja/templates.textile
  83. +231 −0 documentation/manual_ja/test.textile
  84. +52 −0 documentation/manual_ja/usability.textile
  85. +230 −0 documentation/manual_ja/validation-builtin.textile
  86. +458 −0 documentation/manual_ja/validation.textile
  87. +135 −0 documentation/manual_ja/yaml.textile
  88. +11 −115 framework/templates/tags/welcome.html
  89. +116 −0 framework/templates/tags/welcome_en.html
  90. +111 −0 framework/templates/tags/welcome_ja.html
  91. +19 −11 modules/docviewer/app/DocViewerPlugin.java
  92. +57 −37 modules/docviewer/app/controllers/PlayDocumentation.java
  93. +26 −12 modules/docviewer/app/helpers/CheatSheetHelper.java
  94. +49 −0 modules/docviewer/app/helpers/LangMenuHelper.java
  95. +1 −1  modules/docviewer/app/views/PlayDocumentation/cheatSheet.html
  96. +29 −1 modules/docviewer/app/views/PlayDocumentation/page.html
  97. +3 −2 samples-and-tests/i-am-a-developer/tests.py
82 documentation/cheatsheets_ja/commandLine/ch25-CommandLinePlayCommand.textile
View
@@ -0,0 +1,82 @@
+h2. Command line - play command
+
+*classpath*
+算出されたクラスパスを表示します。
+
+*id*
+複数環境設定用のフレームワーク ID を定義します。
+
+*secret*
+暗号化に使われる秘密鍵を生成します。
+
+*install*
+モジュールをインストールします。
+
+*list-modules*
+セントラルモジュールリポジトリから入手可能なモジュールを列挙します。
+
+*modules*
+算出されたモジュールのリストを表示します。
+
+*new*
+新しいアプリケーションを作成します。
+
+*new-module*
+モジュールを作成します。
+
+*build-module*
+モジュールをビルドし、パッケージングします。
+
+*eclipsify*
+Eclipse の全ての設定ファイルを作成します。
+
+*netbeansify*
+NetBeans の全ての設定ファイルを作成します。
+
+*idealize*
+IntelliJ Idea の全ての設定ファイルを作成します。
+
+*javadoc*
+アプリケーションの Javadoc を生成します。
+
+*auto-test*
+全てのアプリケーションのテストを自動的に実行します。
+
+*clean*
+(バイトコードキャッシュを含む) 一時ファイルを削除します。
+
+*test*
+現在のシェルでアプリケーションをテストモードで実行します。
+
+*precompile*
+アプリケーションの起動を高速化するため全ての Java のソースとテンプレートをプリコンパイルします。
+
+*war*
+スタンドアロンの WAR アーカイブとしてアプリケーションをエクスポートします。
+
+*run*
+現在のシェルでアプリケーションを実行します。
+
+*start*
+バックグラウンドでアプリケーションを起動します。
+
+*stop*
+実行中のアプリケーションを停止します。
+
+*restart*
+実行中のアプリケーションを再起動します。
+
+*status*
+実行中のアプリケーションの状態を表示します。
+
+*out*
+logs/system.out ファイルの内容をリアルタイムで表示します。
+
+*pid*
+実行中のアプリケーションの PID を表示します。
+
+*check*
+現在のものより新しい Play framework のリリースがあるかどうかチェックします。
+
+*help*
+指定したコマンドのヘルプを表示します。
27 documentation/cheatsheets_ja/controllers/ch01-ControllerActionSmartbinding.textile
View
@@ -0,0 +1,27 @@
+h2. Controller.action - Smart binding
+
+*==Controller/link?i=32&n=patrick==*
+==public static void link(int i, String n)==
+==public static void link(Integer i, String n)==
+==public static void link(Long i, String n)==
+
+*==Controller/show?id[0]=1&id[1]=2&id[2]=3&id[3]=4==*
+==public static void show(Long[] id)==
+==public static void show(List<Long> id)==
+==public static void show(Set<Long> id)==
+
+*==Controller/get?date=02-18-1972==*
+==public static void get(@As("MM-dd-yyyy") Date date)==
+
+*==(@As(binder=MyCustomStringBinder.class))==*
+Custom parameter binder
+
+*public static void create(String comment, File attachment)*
+multipart/form-data エンコードの POST リクエストとしてファイルを送信します。
+
+*==?client.name=paul&client.email=p@example.com==*
+*public static void create(Client client)*
+JavaBean (POJO) binding
+
+*@NoBinding*
+バインドできないフィールドを示します。
27 documentation/cheatsheets_ja/controllers/ch02-ControllerActionValidation.textile
View
@@ -0,0 +1,27 @@
+h2. Controller.action - Validation
+
+*==@Required String lastname==*
+*==@IsTrue String agree==*
+*==@Max(7500) Integer wordCount==*
+*==@Min(18) Long age==*
+*==@MaxSize(2083) String value==*
+*==@MinSize(42) String value==*
+*==@Email String address==*
+*==@Equals("passwordConfirmation") String password==*
+*==@InFuture String dueDate==*
+*==@InFuture("1979-12-31") String birthDate==*
+*==@Match("[A-Z]{3}") String abbreviation==*
+*==@Match("(directDebit|creditCard|onReceipt)")==*
+*==@Past String actualDepartureDate==*
+*==@Past("1980-01-01") String birthDate==*
+*==@Range(min = 17500, max = 40000) String wordCount==*
+*==@URL String address==*
+*==@IPv4Address String ip==*
+*==@IPv6Address String ip==*
+
+*==@Phone String phone==*
+Relaxed phone validation
+電話番号の緩やかな検証
+
+*==@Valid Person person==*
+JavaBean (POJO) 検証 - Person クラスは検証のアノテーションが必要です。
27 documentation/cheatsheets_ja/controllers/ch03-ControllerSessionManagement.textile
View
@@ -0,0 +1,27 @@
+h2. Controller - Session Management
+
+*警告: Play のセッションは J2EE のセッションではありません*
+session と flash はクッキーを使います! 4KB と 20 個の上限があります。
+
+*session.getId();*
+(たいていの場合持っておかなければいけない) セッション ID を返します。
+
+*session.put(String key, String value);*
+*session.get("user_flag");*
+値は 4KB を上限とする文字列に限られます。
+
+*flash.put(String key, String value);*
+*flash.get(String key);*
+flash エントリは次のリクエストの終了まで廃棄されます。
+
+*Cache.set("key_" + id, product, "30mn");*
+30 分のキャッシュ値をセットします。
+
+*Cache.get("key_" + id, Product.class);*
+キャッシュ値を取得します。キーに対応する値がなければ null を返します。
+
+*Cache.delete("key_" + id);*
+ノンブロッキングのキャッシュ削除
+
+*Cache.safeDelete("key_" + id);*
+ブロッキングのキャッシュ削除
22 documentation/cheatsheets_ja/controllers/ch04-ControllerActionRedirection.textile
View
@@ -0,0 +1,22 @@
+h2. Controller.action - Redirection
+
+*render(params...);*
+与えられたパラメータでテンプレートを text/html としてレンダリングします。
+
+*renderXML(params...);*
+パラメータを application/xml としてレンダリングします。
+
+*renderJson(params...);*
+パラメータを application/json としてレンダリングします。
+
+*renderText(params...);*
+パラメータを text/plain としてレンダリングします。
+
+*renderTemplate("Clients/showClient.html", id, client);*
+デフォルトのテンプレートをバイパスします。
+
+*redirect("http://www.crionics.com");*
+指定された URL に HTTP リダイレクトします。
+
+*From an action, calling another Controller.action()*
+透過的にリダイレクトを生成します。
12 documentation/cheatsheets_ja/controllers/ch05-ControllerJobs.textile
View
@@ -0,0 +1,12 @@
+h2. Controller - Jobs
+
+*==@OnApplicationStart==*
+
+*==@On("0 0 12 &lowast; &lowast; ?")==*
+毎日午後 12:01
+
+*==@On("10 30 12 ? &lowast; MON-FRI")==*
+平日の午後 12:30:10
+
+*==@Every("1h")==*
+*==public class Bootstrap extends Job {public void doJob() {...} }==*
18 documentation/cheatsheets_ja/controllers/ch06-ControllerInterceptions.textile
View
@@ -0,0 +1,18 @@
+h2. Controller - Interceptions
+
+*==@Before ➟ action ➟ @After ➟ template ➟ @Finally==*
+Interceptions evaluation order
+インターセプト評価の順
+
+*==@Before static void checkAuthentification()==*
+*==@After static void log()==*
+*==@Finally static void audit()==*
+You get the idea
+
+*==@With(Secure.class)==*
+*==public class Admin extends Application==*
+コントローラスコープでのカスタムインターセプタ
+
+*==@Catch(value={RuntimeException.class})==*
+*public static void onException(RuntimeException e) {…}*
+コントローラ層での例外ハンドリング
15 documentation/cheatsheets_ja/controllers/ch07-ControllerActionOthers.textile
View
@@ -0,0 +1,15 @@
+h2. Controller.action - Others
+
+*==Logger.info("Action executed ...");==*
+*==Logger.debug("A log message");==*
+*==Logger.error(ex, "Oops");==*
+ロギングの設定は application.conf にあります。
+
+*==@CacheFor("1h") public static void index() { ... }==*
+1時間アクションの実行結果をキャッシュします。
+
+*==Play.configuration.getProperty("blog.title");==*
+設定ファイルにアクセスします。
+
+*==Query query = JPA.em().createQuery("query");==*
+永続化マネージャにアクセスします。
64 documentation/cheatsheets_ja/controllers/ch08-ControllerLibraries.textile
View
@@ -0,0 +1,64 @@
+h2. Controller - Libraries
+
+*==WS.url("http://s.com/posts").get().toJSON();==*
+HTTP GET リクエストを JSON にします。
+
+*==WS.withEncoding("iso-8859-1").url("http://s.com/posts").get().toJSON();==*
+HTTP GET リクエストを iso-8859-1 エンコーディングで JSON にします。
+
+*==WS.url("http://s.com/").post().toXML();==*
+HTTP POST リクエストを XML にします。
+
+*==DB.execute("raw sql");==*
+そのままの SQL を評価します。
+
+*==XML.getDocument(String);==*
+文字列を XML にします。
+
+*==XML.serialize(Document);==*
+XML を文字列にします。
+
+*==XPath.selectNodes(String xpath, Object node);==*
+XPath 表記の評価
+
+*==Files.copy(File,File);==*
+ファイルコピー
+
+*==Files.copyDir(File,File);==*
+再帰的なディレクトリコピー
+
+*==Files.delete(File);==*
+*==Files.deleteDirectory(File);==*
+ファイルやディレクトリの削除
+
+*==IO.readLines(File);==*
+*==IO.readContentAsString(File);==*
+*==IO.readContent(File);==*
+*==IO.write(byte[],File);==*
+ファイルの内容の読み書き
+
+*==Images.crop(File orig,File to, int x1, int y1, int x2, int y2);==*
+*==Images.resize(File orig, File to, int w, int h);==*
+*==Images.toBase64(File image);==*
+便利なメソッド
+
+*==Crypto.encryptAES(String);==*
+*==Crypto.decryptAES(String);==*
+アプリケーションの秘密鍵を使っての暗号化
+
+*==Crypto.passwordHash(String);==*
+MD5 パスワードハッシュを生成します。
+
+*==Codec.UUID();==*
+ユニークな ID を生成します。
+
+*==Codec.byteToHexString(byte[] bytes);==*
+バイト配列を 16進数表記の文字列で書き出します。
+
+*==Codec.encodeBASE64(byte[] value);==*
+*==Codec.decodeBASE64(String base64);==*
+Encode/Decode a base64 value
+base64 のエンコードまたはデコードをします。
+
+*==Codec.hexSHA1(String);==*
+文字列の 16進数表記の SHA1 ハッシュを生成します。
32 documentation/cheatsheets_ja/model/ch14-ModelActionQueries.textile
View
@@ -0,0 +1,32 @@
+h2. Model.action - Queries
+
+*==Query query = JPA.em().createQuery("jpql_query");==*
+永続化マネージャにアクセスします。
+
+*==Post post = Post.findById(id);==*
+*==List<Post> posts = Post.findAll();==*
+find メソッド
+
+*==post.save();==*
+永続化層にオブジェクトを保存します。
+
+*==boolean post.validateAndSave();==*
+オブジェクトを検証して保存した場合に true を返します。検証はアノテーションで行われます。
+
+*==List<Post> posts = Post.all().from(50).fetch(100);==*
+50 番目から 100 番目のレコードを読み込みます。
+
+*==Post.find("select p from Post p, Comment c where c.post==*
+*=== p and c.subject like ?", "%hop%");==*
+ジョインを使ったパラメタ化された参照
+
+*==long userCount = Post.count("author=?", connectedUser);==*
+*==long postCount = Post.count();==*
+レコードをカウントします。
+
+*==JPAPlugin.startTx(boolean readonly);==*
+*==JPAPlugin.closeTx(boolean rollback);==*
+トランザクションを独自で制御するメソッド
+
+*==JPA.setRollbackOnly();==*
+トランザクションを強制的にロールバックします。
16 documentation/cheatsheets_ja/model/ch15-ModelBasics.textile
View
@@ -0,0 +1,16 @@
+h2. Model - Basics
+
+*==@Entity(name="sql_tbl") public class Post extends Model==*
+当該クラスが永続的なものであることを指定します。
+
+*==@Embedded==*
+このフィールドが埋め込まれたものであることを定義します。
+
+*==@EmbeddedId==*
+このフィールドが当該クラスの ID であり、埋め込まれたものであることを定義します。
+
+*==@Embeddable==*
+当該クラスが他の永続的クラスに永続的に埋め込まれることを指定します。
+
+*==@MappedSuperclass==*
+このクラスがサブクラスにマッピングされるための永続的な情報を持っていることを指定します。
11 documentation/cheatsheets_ja/model/ch16-ModelGenerators.textile
View
@@ -0,0 +1,11 @@
+h2. Model - Generators
+
+*==@GeneratedValue(strategy = [NONE, TABLE, SEQUENCE,==*
+*==IDENTITY, AUTO])==*
+インデックスの自動生成に使用します。
+
+*==@SequenceGenerator==*
+永続的なエンティティに使用するデータストア内のシーケンスを使った値のジェネレータを定義します。
+
+*==@TableGenerator==*
+永続的なエンティティに使用するデータストア内のテーブルを使ったシーケンスのジェネレータを定義します。
31 documentation/cheatsheets_ja/model/ch17-ModelRelationalMapping.textile
View
@@ -0,0 +1,31 @@
+h2. Model - Relational mapping
+
+*==@Table(name="sql_tbl", catalog="", schema="")==*
+このクラスが保存されるテーブルを定義します。
+
+*==@Id==*
+ID となるフィールドを定義します。
+
+*==@Version==*
+バージョンを保持しているフィールドを定義します。
+
+*==@Basic==*
+永続的なフィールドを定義します。省略可能です。
+
+*==@Transient==*
+(永続的でない) 一時的なフィールドを定義します。
+
+*==@Lob(fetch=[LAZY, EAGER], type=[BLOB,CLOB])==*
+ラージオブジェクトとして保存されるフィールドを定義します。
+
+*==@UniqueConstraint(primary=false, String columns[])==*
+セカンダリインデックスを定義します。
+
+*==@Temporal(DATE,TIME,TIMESTAMP)==*
+java.util.Date や Calendar 型のフィールドにだけ使われるべきです。
+
+*==@Enumerated(ORDINAL, STRING)==*
+列挙型のクラスを保持するフィールドを定義します。
+
+*==@Column(name="sql_column_name")==*
+フィールド名と異なるテーブルのカラム名を定義します。
21 documentation/cheatsheets_ja/model/ch18-ModelCallbacks.textile
View
@@ -0,0 +1,21 @@
+h2. Model - Callbacks
+
+データベース依存のトリガを実装する便利な方法
+
+*==@PrePersist==*
+永続化前のコールバックメソッドを定義します。
+
+*==@PostPersist==*
+永続化後のコールバックメソッドを定義します。
+
+*==@PreRemove==*
+削除前のコールバックメソッドを定義します。
+
+*==@PostRemove==*
+削除後のコールバックメソッドを定義します。
+
+*==@PreUpdate==*
+更新前のコールバックメソッドを定義します。
+
+*==@PostLoad==*
+更新後のコールバックメソッドを定義します。
23 documentation/cheatsheets_ja/model/ch19-ModelRelations.textile
View
@@ -0,0 +1,23 @@
+h2. Model - Relations
+
+*==@OneToOne(entity, fetch=[LAZY,EAGER], nullable=true)==*
+他の永続的なエンティティとの 1 対 1 の関連フィールドを定義します。
+
+*==@OneToMany(mappedBy="remote_attribute")==*
+他の永続的なエンティティとの 1 対 N の関連フィールドを定義します。
+
+*==@ManyToMany(cascade=[ALL, PERSIST, MERGE,==*
+*==REMOVE, REFRESH, DETACH])==*
+他の永続的なエンティティとの M 対 N の関連フィールドを定義します。
+
+*==@ManyToOne==*
+他の永続的なエンティティとの N 対 1 の関連フィールドを定義します。
+
+*==@JoinColumn(name = "id_connector")==*
+テーブルか外部キーとジョインするときに使用するカラムを定義します。
+
+*==@JoinTable(name = "nm_table", joinColumns ===*
+*=={ @JoinColumn(name = "id_coupon", nullable = false) },==*
+*==inverseJoinColumns = { @JoinColumn(name ===*
+*=="id_campaign", nullable = false) })==*
+ManyToMany の関連をマッピングするために使用します。
12 documentation/cheatsheets_ja/model/ch20-ModelJPAQueries.textile
View
@@ -0,0 +1,12 @@
+h2. Model - JPA Queries
+
+*==@NamedQuery(name="q1", "jpql_query");==*
+永続化単位で使用される名前付き JPQL クエリを定義します。
+
+*==@NamedNativeQuery(name="q2","sql_query")==*
+永続化単位で使用されるネイティブな SQL クエリを定義します。
+
+*==@SqlResultSetMapping==*
+ネイティブな SQL クエリの実行結果をオブジェクトモデルにマッピングするために使用します。
+
+p(note). これは JPA2 アノテーションのサブセットに過ぎません。Hibernate もまた非標準のセットを持っています。
20 documentation/cheatsheets_ja/multiEnvironment/ch26-MultiEnvironment.textile
View
@@ -0,0 +1,20 @@
+h2. Multi-environment
+
+*==# Test configuration==*
+*==%test.db=mem==*
+*==%test.jpa.ddl=create-drop==*
+
+*==# Dev configuration==*
+*==%dev.http.port=8080==*
+*==%dev.application.log=DEBUG==*
+*==%dev.application.mode=dev==*
+
+*==# Production configuration==*
+*==%prod.http.port=80==*
+*==%prod.application.log=INFO==*
+*==%prod.application.mode=prod==*
+
+*==play run --%prod==*
+*==play run --%dev==*
+*==play test==*
+これは適切な設定を選びます。
28 documentation/cheatsheets_ja/templates/ch09-TemplateImplicitObjects.textile
View
@@ -0,0 +1,28 @@
+h2. Template - Implicit objects
+
+*errors*
+コントローラで発生した検証エラー
+
+*flash*
+flash スコープ
+
+*lang*
+通信に使用されている言語
+
+*messages*
+ローカライズされたメッセージの map
+
+*out*
+The output stream writer
+
+*params*
+パラメータ
+
+*play*
+フレームワークのメインのクラス
+
+*request*
+HTTP リクエスト
+
+*session*
+セッションスコープ
31 documentation/cheatsheets_ja/templates/ch10-TemplateTagGrammar.textile
View
@@ -0,0 +1,31 @@
+h2. Template - Tag grammar
+
+*==${ client.name }==*
+変数を評価し出力します。
+
+*==${ client?.name }==*
+client が null でなければ client.name を表示します。
+
+*==@{ Controller.action() }==*
+アクションへの相対パスの URL を計算します。
+
+*==@{ Controller.action().secure() }==*
+アクションへの HTTPS での相対パスの URL を計算します。
+
+*==@@{ Controller.action() }==*
+アクションへの絶対パスの URL を計算します。
+
+*==@{'path/to/static_content'}==*
+==&lt;img src="@{'/public/images/jpdf.png'}" class="center"/&gt;==
+
+*==&{ message.key }==*
+メッセージは conf/messages で管理され、多言語対応しています。
+
+*==&lowast;{ これはコメントです }&lowast;==*
+これ以上何を言えばいい?
+
+*==%{ out.print("HelloWorld") }%==*
+UI ロジック用の Groovy スクリプト
+
+*==#{ my.custom.tag /}==*
+典型的なカスタムタグ - page コンテキストは共有しません。
52 documentation/cheatsheets_ja/templates/ch11-TemplateStandardTags.textile
View
@@ -0,0 +1,52 @@
+h2. Template - Standard Tags
+
+*==#{extends ʻpage.htmlʼ/}==*
+*==#{doLayout /}==*
+マスタテンプレートのデコレータ
+
+*==#{get 'title'}Used if title not set#{/get}==*
+*==#{set title:ʻHome Pageʼ}==*
+ページとマスタテンプレート間で共有される変数
+
+*==#{include 'tree.html'/}==*
+ページの断片をインクルードします。 - page コンテキストは共有されます。
+
+*==#{script id:'myscript' , src:ʻscript.js', charset:'utf-8' /}==*
+*==#{stylesheet id:'main', media:'print', src:'print.css' /}==*
+スクリプトとスタイルシートをインポートします。
+
+*==#{a @Application.logout() }Disconnect#{/a}==*
+*==#{form @Client.create() , id:'form' enctype:'multipart/form-==*
+*==data' } ... #{/form}==*
+アンカーやフォームを作るのに便利なタグ
+
+*==#{verbatim}${'&amp;'}#{/verbatim}==*
+HTML エスケープを無効化します。
+
+*==#{i18n /}==*
+ローカライズされたメッセージを Javascript にエクスポートします。
+
+*==#{ifErrors} &lt;p&gt;Error(s) found!&lt;/p&gt; #{/ifErrors}==*
+検証エラーをチェックします。
+
+*==#{ifError 'user.name'} #{error 'user.name' /} #{/ifError}==*
+指定されたエラーをチェックします。
+
+*==#{errors} &lt;li&gt;${error}&lt;/li&gt; #{/errors}==*
+検証エラーを繰り返し処理します。
+
+*==#{if cond}...#{/if}#{elseif cond}...#{/elseif}#{else}...#{/else}==*
+*==#{ifnot cond}...#{/ifnot}==*
+条件構文
+
+*==#{list items:0..10, as:'i'}${i}#{/list}==*
+*==#{list items:'a'..'z', as:'l'}${l} ${l_isLast ?'':'|' }#{/list}==*
+*==#{list users}${_}#{/list}==*
+ループ構文
+
+*==#{list items:task, as:'task'}${task}#{/list}==*
+*==#{else}No tasks on the list#{/else}==*
+Tip: else は list と一緒に使えます。
+
+*==#{cache ʻkeyʼ, for:ʼ15minʼ}...#{/cache}==*
+15 分間コンテンツをキャッシュします。
8 documentation/cheatsheets_ja/templates/ch12-TemplateCustomTags.textile
View
@@ -0,0 +1,8 @@
+h2. Template - Custom Tags
+
+*==@FastTags.Namespace("domain")==*
+*==public class RecaptchaTag extends FastTags {==*
+*==public static void _recaptcha(Map<?, ?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) { …==*
+
+*==/app/view/tags/domain/mytag.tag==*
+カスタムタグは {#domain.mytag/} で呼び出せます。
77 documentation/cheatsheets_ja/templates/ch13-TemplateGroovyExtension.textile
View
@@ -0,0 +1,77 @@
+h2. Template - Groovy extension
+
+*==${ ['red', 'green', 'blue'].join('/') }==*
+red/green/blue
+
+*==${ (["red", "green", "blue"] as String[]).add('pink').join(' ') }==*
+red green blue pink
+
+*==${ (['red', 'green', 'blue'] as String[]).contains('green') }==*
+true
+
+*==${(['red', 'gr', 'blue'] as String[]).remove('gr').join(' ')}==*
+red blue
+
+*==${ ['red', 'green', 'blue'].last() }==*
+blue
+
+*==${ new Date(new Date().getTime() - 1000000).since() }==*
+16 分前
+
+*==${new Date(1275910970000).format('dd MMMM yyyy==*
+*==hh:mm:ss')}==*
+07 June 2010 01:42:50
+
+*==${ 1275910970000.asdate('dd MMMM yyyy hh:mm:ss') }==*
+07 June 2010 01:42:50
+
+*==${726016L.formatSize()}==*
+709KB
+
+*==${ 42.formatCurrency('EUR').raw() }==*
+&euro; 42.00
+
+*==${ 42.page(10) }==*
+5
+
+*==journ${ ['cnn', 'c+', 'f2'].pluralize('al', 'aux') }==*
+journaux
+
+*==${ "lorum ipsum dolor".capAll() }==*
+Lorum Ipsum Dolor
+
+*==${ "lorum ipsum dolor".camelCase() }==*
+LorumIpsumDolor
+
+*==${ "lorum ipsum dolor".capFirst() }==*
+Lorum ipsum dolor
+
+*==${ "lorum ipsum dolor".cut('um') }==*
+lor ips dolor
+
+*==${ "The &lt;blink&gt;tag&lt;/blink&gt; is evil".escape().raw() }==*
+The &lt;blink&gt;tag&lt;/blink&gt; is evil
+
+*==${ "one\ntwo".nl2br() }==*
+==one&lt;br/&gt;two==
+
+*==${ '<' } ${ '<'.raw() }==*
+&lt; <
+
+*==${ " (') (\") ".escapeJavaScript().raw() }==*
+==(\') (\")==
+
+*==${ "".yesno('yes', 'no') }==*
+no
+
+*==${ "not empty".yesno('yes', 'no') }==*
+yes
+
+*==${"Stéphane Épardaud".noAccents()}==*
+Stephane Epardaud
+
+*==${ "The Play! frameworkʼs manual".slugify() }==*
+the-play-framework-s-manual
+
+*==${ "x".pad(4).raw() }==*
+x&nbsp;&nbsp;&nbsp;
24 documentation/cheatsheets_ja/tests/ch21-TestUnitTests.textile
View
@@ -0,0 +1,24 @@
+h2. Test - Unit Tests
+
+*==@Test public void getRental() { ... }==*
+*==@Test (expected = NumberFormatException.class )==*
+*==@Ignore==*
+全てのエラーを無視します。
+
+*==@Test (timeout=400)==*
+テストは 400 ミリ秒後に失敗します。
+
+*==@Before public void prepareRecords();==*
+各ユニットテストの前に実行されます。
+
+*==@After public void cleanupJunk()==*
+各ユニットテストの後に実行されます。
+
+*==@BeforeClass void whenTestClassInstanciated();==*
+当該テストクラスがインスタンス化されたときに一度だけ実行されます。
+
+*==@AfterClass void whenTestClassCompleted()==*
+当該テストクラスにある全てのテストが終了した時に一度だけ実行されます。
+
+*==Assert.assert==*
+たくさんのアサーションがあります。どのようなものがあるかは調べてください。
16 documentation/cheatsheets_ja/tests/ch22-TestFunctionalTests.textile
View
@@ -0,0 +1,16 @@
+h2. Test - Functional Tests
+
+*==public class ApplicationTest extends FunctionalTest==*
+機能テストは HTTP を取り入れたユニットテストです。
+
+*==newRequest()==*
+*==newResponse()==*
+*==GET(request, url)==*
+*==PUT(request, url)==*
+*==POST(request,url)==*
+*==DELETE(request,url)==*
+*==assertStatus(404, response)==*
+*==assertHeaderEquals(headerName, value, response)==*
+*==assertContentEquals(content, response)==*
+*==assertContentType(type,response)==*
+*==clearCookies()==*
13 documentation/cheatsheets_ja/tests/ch23-TestSeleniumTests.textile
View
@@ -0,0 +1,13 @@
+h2. Test - Selenium Tests
+
+*==#{selenium}==*
+clearSession()
+open('/admin')
+assertTextPresent('Login')
+type('login', 'admin')
+type('password', 'secret')
+clickAndWait('signin')
+
+// ユーザが正常にログインしているか検証します。
+assertText('success', 'Welcome admin!')
+*==#{/selenium}==*
9 documentation/cheatsheets_ja/tests/ch24-TestDataloader.textile
View
@@ -0,0 +1,9 @@
+h2. Test - Data loader
+
+*==@Before public void setUp() { Fixtures.deleteAll();==*
+*==Fixtures.load("data.yml");}==*
+Fixtures はユニットテストを実行する前にデータストアを初期化するために使用します。
+
+*==#{fixture delete:'all', load:'data.yml' /}==*
+*==#{selenium} ... #{/selenium}==*
+Selenium テストを使うときも同様に出来ます。
123 documentation/manual_ja/5things.textile
View
@@ -0,0 +1,123 @@
+h1. Play でできる 5 つのすごいこと
+
+5 つの例を通して Play framework の背後にある哲学を見てみましょう。
+
+h2. <a>HTTP パラメータの Java メソッド引数への紐付け</a>
+
+Play では Java のコードから簡単に HTTP パラメータを探すことができます。HTTP パラメータと同じ名前でメソッド引数を宣言するだけです。
+
+例えば、このようなリクエスト場合:
+
+bc. /articles/archive?date=08/01/08&page=2
+
+Java のメソッド引数として宣言することで @data@ パラメータと @page@ パラメータを検索することができます:
+
+bc. public static void archive(Date date, Integer page) {
+ List<Article> articles = Articles.fromArchive(date, page);
+ render(articles);
+}
+
+Play は HTTP パラメータの値を Java オブジェクトに変換するために、static メソッドの引数を使用します。
+
+このスマートな紐付けは **どのようなクラス** についても動作します。
+
+bc. public class Person {
+ public String name;
+ public Integer age;
+}
+
+person を追加するシンプルなアクションコントローラはこんな感じかもしれません:
+
+bc. public static void add(Person p) {
+ p.save();
+}
+
+HTML フォームのフィールドには person を構成する名前を定義します:
+
+bc. <form action="/Directory/add" method="POST">
+ Name: <input type="text" name="p.name" />
+ Age: <input type="text" name="p.age" />
+</form>
+
+
+h2. <a>対応する Java メソッドの実行によるアクションへのリダイレクト</a>
+
+Play には Java Servlet の @forward@ コマンドに該当するものは存在しません。しかし、とてもシンプルに別のアクションへリダイレクトすることができます。単に対応する Java メソッドを実行すれば、 Play は適切な HTTP 'Redirect' レスポンスを生成します。
+
+bc. public static void show(Long id) {
+ Article article = Article.findById(id);
+ render(article);
+}
+
+public static void edit(Long id, String title) {
+ Article article = Article.findById(id);
+ article.title = title;
+ article.save();
+ show(id);
+}
+
+
+edit アクションの終わりの部分に注目してください。show アクションにリダイレクトします。
+
+テンプレートにおいても、同じような構文でリンクを生成することができます:
+
+bc. <a href="@{Article.show(article.id)}">${article.title}</a>
+
+これは以下ような HTML を生成します:
+
+bc. <a href="/articles/15">My new article</a>
+
+
+h2. <a>Java オブジェクトをテンプレートに引き渡すとき、同じことをくり返してはいけません</a>
+
+ほとんどの Java フレームワークでは、Java オブジェクトをテンプレートシステムに引き渡すためには以下のように書かなければなりません:
+
+bc. Article article = Article.findById(id);
+User user = User.getConnected();
+Map<String, Object> model = new HashMap<String,Object>();
+model.put("article", article);
+model.put("user", user);
+render(model);
+
+Play では単純にこのように書くことができます:
+
+bc. Article article = Article.findById(id);
+User user = User.getConnected();
+render(article, user);
+
+テンプレートでは Java のローカル名を使ってオブジェクトを参照してください。これで役に立たないコードを省くことができます...
+
+h2. <a>強化された JPA</a>
+
+JPA は間違いなく Java におけるベストなオブジェクト-リレーショナル マッピング (ORM) API です。もし JPA を知っているなら、Play で JPA がいとも簡単に利用できることに驚くでしょう。なんの設定も無しに Play は自動的に JPA のエンティティマネージャを起動し、コードがリロードされたときはまるで魔法のように同期を行います。
+
+さらに、スーパークラス @play.db.jpa.Model@ を使うことでコードをよりきれいにすることもできます。こんな感じです:
+
+bc. public void messages(int page) {
+ User connectedUser = User.find("byEmail", connected()).first();
+ List<Message> messages = Message.find(
+ "user = ? and read = false order by date desc",
+ connectedUser
+ ).from(page * 10).fetch(10);
+ render(connectedUser, messages);
+}
+
+h2. <a>簡単なファイルアップロード管理</a>
+
+Play におけるファイルアップロード管理は非常にシンプルです。
+
+HTML フォームはこんな感じで:
+
+bc. #{form @uploadPhoto(), enctype:'multipart/form-data'}
+ <input type="text" name="title" />
+ <input type="file" id="photo" name="photo" />
+ <input type="submit" value="Send it..." />
+#{/}
+
+Java コードはこんな感じです:
+
+bc. public static void uploadPhoto(String title, File photo) {
+ ...
+}
+
+これ以上簡単になりますかね?
68 documentation/manual_ja/ajax.textile
View
@@ -0,0 +1,68 @@
+h1. Play フレームワークにおける Ajax
+
+Play フレームワークは、はじめから "jQuery":http://jquery.com を含めてリリースされており、簡単に Ajax リクエストを行うことができます。このセクションは、どのようにして Play フレームワークにおいて "jQuery":http://jquery.com を効率的に使用するかについて記載します。
+
+Play フレームワークには、コントローラから透過的にメソッド定義を取得する、手軽な "jsAction":tags#jsaction タグも含まれています。
+
+h2. <a name="jsaction">jQuery を jsAction タグと使う</a>
+
+この @#{jsAction /}@ タグは、サーバアクションに基づいた URL と自由な変数から成る JavaScript 関数を返却します。この関数では AJAX リクエストを行わないので、返却された URL を使って手作業で Ajax リクエストを実行する必要があります。
+
+例を見てみましょう:
+
+bc. GET /hotels/list Hotels.list
+
+クライアント側でこのルートをインポートすることができます:
+
+bc. <script type="text/javascript">
+ var listAction = #{jsAction @list(':search', ':size', ':page') /}
+ $('#result').load(
+ listAction({search: 'x', size: '10', page: '1'}),
+ function() {
+ $('#content').css('visibility', 'visible')
+ }
+ )
+</script>
+
+この例では、デフォルトの Application コントローラの list メソッドを指定しています。3 つの引数: search、size そして page も渡しています。この実行結果は listAction 変数に保存されます。ここで、jQuery と @load@ 関数を使ってリクエスト (実際には HTTP GET リクエスト) を実行します。
+
+実際のところ、以下のリクエストが発行されます:
+
+bc. GET /hotels/list?search=x&size=10&page=1
+
+このケースでは、発行したリクエストは HTML データを返します。
+
+jQuery にデータを解釈させるために JSON または XML を返すことも可能です。コントローラで適切な render メソッド (renderJSON、renderXML または XML テンプレート) を使用してください。
+
+より詳しい情報については、"jQuery":http://docs.jquery.com/Main_Page ドキュメントを参照してください。
+
+jQuery メソッドを以下のように変更することで POST も発行できることに注意してください:
+
+bc. $.post(listAction(), function(data) {
+ $('#result').html(data);
+});
+
+h2. <a name="jsaction">jsRoute タグを jQuery と使う</a>
+
+生成されたルートをもっと制御するために、 **#{jsAction /}** タグと似ていますが、サーバのアクションに基づく URL を構築する関数と、関連する HTTP メソッド (GET, POST, その他) の両方を含むオブジェクトを返却する "jsRoute":tags#jsroute タグがあります。
+
+例:
+
+bc. PUT /users/{id} Users.update
+
+その後、テンプレートでは:
+
+bc. <script type="text/javascript">
+ var updateUserRoute = #{jsRoute @Users.update(':id') /}
+ $.ajax({
+ url: updateUserRoute.url({id: userId}),
+ type: updateUserRoute.method,
+ data: 'user.name=Guillaume'
+ });
+</script>
+
+このアプローチなら、routes ファイルにて HTTP メソッドの変更を決断した場合でも、テンプレートを更新する必要はありません。
+
+p(note). **考察を続けます**
+
+%(next)"国際化":i18n% を取り扱ってみましょう。
199 documentation/manual_ja/asynchronous.textile
View
@@ -0,0 +1,199 @@
+h1. HTTP による非同期プログラミング
+
+この節では、数千の同時接続までスケールし得る典型的な長時間ポーリング、ストリーミング、そしてその他の "Comet スタイル":http://en.wikipedia.org/wiki/Comet_(programming%29 のアプリケーションを達成するために、Play アプリケーションで非同期処理を取り扱う方法を説明します。
+
+h2. HTTP リクエストの中断
+
+Play はとても短いリクエストで動作することを意図しています。Play は HTTP コネクタによってキューイングされたリクエストを処理するために固定のスレッドプールを使用します。最適な結果を得るために、このスレッドプールは可能な限り小さくあるべきです。デフォルトのプールサイズを設定するための最適値として、典型的には @プロセッサ数 + 1@ を使用します。
+
+これは、もしリクエストの処理時間がとても長い場合 (例えば、長い計算を待つなど) に、リクエストがスレッドプールをブロックし、アプリケーションの応答性に不利益をもたらすことを意味します。もちろん、プールにより多くのスレッドを追加することもできますが、リソースを浪費する結果となるかも知れませんし、いずれにしてもプールのサイズは決して無限にはなりません。
+
+ブラウザが画面に表示する新しいメッセージを待つためにブロッキング HTTP リクエストを送信するチャットアプリケーションを考えてみましょう。これらのリクエストはとてもとても長く (典型的には数秒) なることがあり、スレッドプールをブロックします。もしこのチャットアプリケーションに 100 ユーザが同時に接続できるよう計画しているのであれば、最低でも 100 スレッドを供給する必要があるでしょう。ええ、それくらいなら実現可能です。でも 1,000 ユーザではどうでしょう? 10,000 ユーザなら?
+
+これらのユースケースを解決するために、Play ではリクエストを一時的に中断することができます。HTTP リクエストは接続されたままですが、リクエストの実行はスレッドプールの外に押し出され、あとで再実行されます。固定した遅延のあとにリクエストを実行するか、または @Promise@ の値が利用可能になるのを待つよう Play に伝えることができます。
+
+p(note). **Tip**. 本物の例を @samples-and-tests/chat@ で見ることができます。
+
+例えば、このアクションはとても長いジョブを起動し、HTTP レスポンスに結果を返す前にジョブの完了を待機します:
+
+bc. public static void generatePDF(Long reportId) {
+ Promise<InputStream> pdf = new ReportAsPDFJob(report).now();
+ InputStream pdfStream = await(pdf);
+ renderBinary(pdfStream);
+}
+
+ここでは @Promise<InputStream>@ が回復するまでリクエストを中断するよう Play に依頼するために @await(…)@ を使用しています。
+
+h3. 継続
+
+フレームワークは、他のリクエストに供給するために使用していたスレッドを回収する必要があるので、コードの実行を中断しなければなりません。以前のバージョンの Play の @await(…)@ は、アクションを中断し、その後に最初から再度実行する @waitFor(…)@ と等価でした。
+
+非同期処理をより簡単に扱うために、継続を紹介します。継続はコードの中断と透過的な再開を可能にします。このため、以下のようにとても命令的にコードを書くことができます:
+
+bc. public static void computeSomething() {
+ Promise<String> delayedResult = veryLongComputation(…);
+ String result = await(delayedResult);
+ render(result);
+}
+
+ここでは実際のところ、コードは二つのステップ、二つの異なるスレッドで実行されます。しかし、ご覧のとおりアプリケーションコードはとても透過的です。
+
+@await(…)@ と継続を使って、以下のようにループを書くことができます:
+
+bc. public static void loopWithoutBlocking() {
+ for(int i=0; i<=10; i++) {
+ Logger.info(i);
+ await("1s");
+ }
+ renderText("Loop finished");
+}
+
+リクエストを処理するためにひとつのスレッドしか使いませんが、Play はこれらのループを複数のリクエストに対して同時に並列実行することができます。
+
+より現実的な例として、リモート URL からの非同期なコンテンツ取得があります。次の例では、三つのリモート HTTP リクエストを平行して実行します: それぞれの @play.libs.WS.WSRequest.getAsync()@ メソッドに対する呼び出しは非同期に GET リクエストを実行し、 @play.libs.F.Promise@ を返却します。このアクションメソッドは、三つの @Promise@ インスタンスの組み合わせについて @await(…)@ を呼び出すことで、受け取った HTTP リクエストを中断します。三つ全てのリモート呼び出しがレスポンスを生成したら、スレッドは処理を再開し、レスポンスをレンダリングします。
+
+bc. public class AsyncTest extends Controller {
+
+ public static void remoteData() {
+ F.Promise<WS.HttpResponse> r1 = WS.url("http://example.org/1").getAsync();
+ F.Promise<WS.HttpResponse> r2 = WS.url("http://example.org/2").getAsync();
+ F.Promise<WS.HttpResponse> r3 = WS.url("http://example.org/3").getAsync();
+
+ F.Promise<List<WS.HttpResponse>> promises = F.Promise.waitAll(r1, r2, r3);
+
+ // Suspend processing here, until all three remote calls are complete.
+ List<WS.HttpResponse> httpResponses = await(promises);
+
+ render(httpResponses);
+ }
+}
+
+
+h3. コールバック
+
+前述した三つの非同期リモートリクエストの例を実装する別の方法は、コールバックを使うことです。ここでは @await(…)@ の呼び出しに、すべての @promises@ が完了した時に実行されるコールバックである @play.libs.F.Action@ の実装が含まれています。
+
+bc. public class AsyncTest extends Controller {
+
+ public static void remoteData() {
+ F.Promise<WS.HttpResponse> r1 = WS.url("http://example.org/1").getAsync();
+ F.Promise<WS.HttpResponse> r2 = WS.url("http://example.org/2").getAsync();
+ F.Promise<WS.HttpResponse> r3 = WS.url("http://example.org/3").getAsync();
+
+ F.Promise<List<WS.HttpResponse>> promises = F.Promise.waitAll(r1, r2, r3);
+
+ // Suspend processing here, until all three remote calls are complete.
+ await(promises, new F.Action<List<WS.HttpResponse>>() {
+ public void invoke(List<WS.HttpResponse> httpResponses) {
+ render(httpResponses);
+ }
+ });
+ }
+}
+
+
+h2. HTTP レスポンスストリーミング
+
+これで、リクエストをブロックせずにループを行うことができるようになったので、処理結果の一部が利用可能になり次第、ブラウザにデータを送りたくなるのではないでしょうか。それこそが @Content-Type:Chunked@ HTTP レスポンス型のポイントです。複数のチャンクを使って HTTP レスポンスを何度も送ることができます。ブラウザはこれらのチャンクが発行され次第、これを受け取ります。
+
+今では @await(…)@ と継続を使ってこれを達成することができます:
+
+bc. public static void generateLargeCSV() {
+ CSVGenerator generator = new CSVGenerator();
+ response.contentType = "text/csv";
+ while(generator.hasMoreData()) {
+ String someCsvData = await(generator.nextDataChunk());
+ response.writeChunk(someCsvData);
+ }
+}
+
+もし CSV の生成に一時間かかったとしても、生成されたデータが利用可能になり次第、クライアントに送り返すことで、Play はひとつのスレッドを使って複数のリクエストを同時に処理することができます。
+
+
+h2. WebSockets の使用
+
+WebSockets は、ブラウザとアプリケーション間の双方向コミュニケーションチャンネルを開く、ひとつの方法です。ブラウザ側で "ws://" という url を使ってソケットを開きます。
+
+bc. new Socket("ws://localhost:9000/helloSocket?name=Guillaume")
+
+Play 側では WS ルートを定義します:
+
+bc. WS /helloSocket MyWebSocket.hello
+
+@MyWebSocket@ は @WebSocketController@ です。WebSocket コントローラは標準的な HTTP コントローラに似ていますが、異なる概念を取り扱います。
+
+* リクエストオブジェクトを持ちますが、レスポンスオブジェクトは持ちません。
+* セッションにアクセスできますが、読み出し専用です。
+* @renderArgs@, @routeArgs@ とフラッシュスコープを持ちません。
+* ルートパターンまたはクエリ文字列からのパラメータのみ読むことができます。
+* 二つのコミュニケーションチャンネル: inbound と outbound を持ちます。
+
+クライアントが @ws://localhost:9000/helloSocket@ ソケットに接続すると、Play は @MyWebSocket.hello@ アクションメソッドを起動します。一旦 @MyWebSocket.hello@ アクションメソッドが終了するとソケットは閉じられます。
+
+このため、とても基本的なソケットの例は以下のようになります:
+
+bc. public class MyWebSocket extends WebSocketController {
+
+ public static void hello(String name) {
+ outbound.send("Hello %s!", name);
+ }
+}
+
+ここでは、クライアントはソケットに接続すると‘Hello Guillaume’というメッセージを受け取り、その後 Play はソケットを閉じます。
+
+もちろん、通常は直ちにソケットを閉じたいと思わないでしょう。これは @await(…)@ と継続を使って容易に達成できます。
+
+基本的なエコーサーバの例です:
+
+bc. public class MyWebSocket extends WebSocketController {
+
+ public static void echo() {
+ while(inbound.isOpen()) {
+ WebSocketEvent e = await(inbound.nextEvent());
+ if(e instanceof WebSocketFrame) {
+ WebSocketFrame frame = (WebSocketFrame)e;
+ if(!e.isBinary) {
+ if(frame.textData.equals("quit")) {
+ outbound.send("Bye!");
+ disconnect();
+ } else {
+ outbound.send("Echo: %s", frame.textData);
+ }
+ }
+ }
+ if(e instanceof WebSocketClose) {
+ Logger.info("Socket closed!");
+ }
+ }
+ }
+
+}
+
+上記の例において、ネストされた‘if’と‘キャスト’の海は書くのが退屈でエラーを起こしがちでした。この点で Java は最低です。このようなシンプルな場合でさえ容易に扱えません。複数のストリームを結びつけ、より多くのイベントタイプが存在するような、より複雑なケースにおいては悪夢のようになることでしょう。
+
+これこそが、私たちが "play.libs.F":libs#FunctionalprogrammingwithJava ライブラリにおいてある種の基本的なパターンマッチングを導入した理由です。
+
+これにより上記の例を次のように書き直すことができます:
+
+bc. public static void echo() {
+ while(inbound.isOpen()) {
+ WebSocketEvent e = await(inbound.nextEvent());
+
+ for(String quit: TextFrame.and(Equals("quit")).match(e)) {
+ outbound.send("Bye!");
+ disconnect();
+ }
+
+ for(String message: TextFrame.match(e)) {
+ outbound.send("Echo: %s", message);
+ }
+
+ for(WebSocketClose closed: SocketClosed.match(e)) {
+ Logger.info("Socket closed!");
+ }
+ }
+}
+
+p(note). **考察を続けます**
+
+次は %(next)"Ajax リクエスト":ajax% を行ってみましょう。
103 documentation/manual_ja/cache.textile
View
@@ -0,0 +1,103 @@
+h1. キャッシュの使用
+
+パフォーマンスの高いシステムを作成するため、データのキャッシュが必要になる場合があります。Play にはキャッシュライブラリがあり、分散環境下では "Memcahed":http://www.danga.com/memcached/ を使用します。
+
+Memcached を設定しない場合、Play は JVM ヒープにデータを保存するスタンドアロンキャッシュを使用します。JVM へのデータのキャッシュは、Play の ‘何も共有しない’ という前提を覆します: 複数のサーバで実行したアプリケーションの振る舞いが一貫していると期待することはできません。それぞれのアプリケーションインスタンスは異なるデータのコピーを持ちます。
+
+キャッシュの規約がはっきりしていることを理解することは重要です: キャッシュにデータを置いた場合、このデータが永久に残り続けると期待することはできません。実際のところ、期待すべきではありません。キャッシュは高速ですが、その値は失効しますし、(永続的にバックアップしない限り) 基本的にキャッシュはメモリ上にのみ存在します。
+
+このため、期待するデータが無い場合、再度データを置くことが、キャッシュを使う最善の方法です:
+
+bc. public static void allProducts() {
+ List<Product> products = Cache.get("products", List.class);
+ if(products == null) {
+ products = Product.findAll();
+ Cache.set("products", products, "30mn");
+ }
+ render(products);
+}
+
+h2. <a name="api">キャッシュ API</a>
+
+キャッシュ API は @play.cache.Cache@ クラスによって提供されます。このクラスには、キャッシュのデータを設定する、置き換える、取得する、と言ったひと揃えのメソッドがあります。それぞれのメソッドの振る舞いを正確に理解するには、Memcached のドキュメントを参照してください。
+
+いくつか例を示します:
+
+bc. public static void showProduct(String id) {
+ Product product = Cache.get("product_" + id, Product.class);
+ if(product == null) {
+ product = Product.findById(id);
+ Cache.set("product_" + id, product, "30mn");
+ }
+ render(product);
+}
+
+public static void addProduct(String name, int price) {
+ Product product = new Product(name, price);
+ product.save();
+ showProduct(product.id);
+}
+
+public static void editProduct(String id, String name, int price) {
+ Product product = Product.findById(id);
+ product.name = name;
+ product.price = price;
+ Cache.set("product_" + id, product, "30mn");
+ showProduct(id);
+}
+
+public static void deleteProduct(String id) {
+ Product product = Product.findById(id);
+ product.delete();
+ Cache.delete("product_" + id);
+ allProducts();
+}
+
+いくつかのメソッドは @safe@ という接頭辞で始まります - 例えば、 @safeDelete@ や @safeSet@ という具合です。標準のメソッドは処理をブロックしません。これは、以下のメソッド呼び出しを発行した際:
+
+bc. Cache.delete("product_" + id);
+
+@delete@ メソッドが、キャッシュオブジェクトが実際に削除されるまで待たずに、直ちにリターンすることを意味します。このため、このオブジェクトはまだ存在するかもしれない場合には、エラー - 例えば IO エラー - が発生します。
+
+処理を続行する前に、このオブジェクトを確実に削除したい場合には、 @safeDelete@ メソッドを使うことができます:
+
+bc. Cache.safeDelete("product_" + id);
+
+このメソッドは処理をブロックし、オブジェクトが削除されたかどうかを示す boolean 型の値を返します。以上より、キャッシュからあるアイテムが削除されたことを保証する完全なパターンは、以下のようになります:
+
+bc. if(!Cache.safeDelete("product_" + id)) {
+ throw new Exception("Oops, the product has not been removed from the cache");
+}
+...
+
+これらの処理をブロックする @safe@ メソッドの呼び出しは、アプリケーションを遅くすることに注意してください。このため、これらのメソッドは必要な場合にのみ使用してください。
+
+@expiration == "0s"@ (ゼロ秒) を指定した場合の実際の有効期限はキャッシュ実装によって異なることにも注意してください。
+
+h2. <a name="session">セッションをキャッシュとして使ってはいけません!</a>
+
+インメモリのセッション実装を使用するフレームワークを使ってきたならば、Play が小さな String 型のデータのみを HTTP セッションに保存することを許可することを不満に感じるかもしれません。しかし、セッションはアプリケーションデータをキャッシュする場所ではないので、このほうが良いのです!
+
+このため、以下のようなやり方に慣れているならば:
+
+bc. httpServletRequest.getSession().put("userProducts", products);
+...
+// and then in subsequent requests
+products = (List<Product>)httpServletRequest.getSession().get("userProducts");
+
+Play ではちょっと違ったやり方で同じ効果を得られます。以下のほうがより良いアプローチだと考えます:
+
+bc. Cache.set(session.getId(), products);
+...
+// and then in subsequent requests
+List<Product> products = Cache.get(session.getId(), List.class)
+
+ここでは、Cache の中のそれぞれの情報が一意性を保てるように、一意な UUID を使用しました。セッションオブジェクトとは違い、キャッシュはどのユーザにも紐付かないことを忘れないでください!
+
+h2. <a name="memcached">memcached の設定</a>
+
+Memcached の実際の実装を利用する場合は、 "memcached configuration":configuration#memcached において Memcached を利用可能にし、"memcached.host configuration":configuration#memcached.host でデーモンのアドレスを定義します:
+
+p(note). **考察を続けます**
+
+%(next)"メール送信":emails% について学びましょう。
916 documentation/manual_ja/configuration.textile
View
@@ -0,0 +1,916 @@
+h1. 設定パラメータ
+
+@conf/application.conf@ ファイルの設定キーに値を設定して Play のアプリケーションを設定しましょう。参照:
+
+* "主要な概念 - conf ディレクトリ":main#conf
+* "複数環境用 application.conf の管理":ids
+* "アプリケーションの本番稼動":production
+
+h2(#application). アプリケーション設定
+
+
+h3(#application.baseUrl). application.baseUrl
+
+アプリケーションベース URL は絶対 URL の逆引きに使われます。このアプリケーションベース URL は e メールのレンダリングのように @Http.Request@ を介さない <code>@@{..}</code> テンプレート構文やジョブ内で使われます。例えば @dev@ モード用の設定は次のようにし:
+
+bc. application.baseUrl=http://localhost:9000/
+
+@prod@ モード用の設定は次のようにします:
+
+bc. %production.application.baseUrl=http://www.yourdomain.com/
+
+
+h3(#application.defaultCookieDomain). application.defaultCookieDomain
+
+サブドメイン間で共有される session/cookie を有効にします。例えば、 @foo.example.com@ や @bar.example.com@ などのように ‘.example.com’ で終わる全てのドメインで有効な cookie を生成するには次のようにします:
+
+bc. application.defaultCookieDomain=.example.com
+
+デフォルト: cookie は特定のドメインでのみ有効です。
+
+
+h3(#application.lang.cookie). application.lang.cookie
+
+現在の言語を格納するために使われる cookie の名前です。言語は @play.i18n.Lang.change(String locale)@ で設定されます。Play アプリケーションと言語設定を分けたい場合に変更できます。設定例:
+
+bc. application.lang.cookie=MYAPP_LANG
+
+デフォルト: @PLAY_LANG@
+
+
+h3(#application.langs). application.langs
+
+アプリケーションで使われるロケールを定義します。 @conf/messages.{locale}@ ファイルにローカライズされたメッセージを置くことができます。設定する値はカンマ区切りの言語コードのリストです。設定例:
+
+bc. application.langs=fr,en,ja
+
+デフォルト: 追加言語はありません。
+
+
+h3(#application.log). application.log
+
+アプリケーションのログレベルを指定します。設定例:
+
+bc. application.log=DEBUG
+
+デフォルト: @INFO@
+
+関連項目: "ログの設定":logs.
+
+
+h3(#application.log.path). application.log.path
+
+ログ出力をカスタマイズするための Log4J 設定ファイルのパス。パスを指定しないとき Play は @conf@ ディレクトリに @log4j.properties@ ファイルがあればロードします。
+
+bc. application.log.path=/log4j.properties
+
+デフォルト: @/log4j.xml@ がなければ @/log4j.properties@
+
+
+h3(#application.log.recordCaller). application.log.recordCaller
+
+呼び出し元のメソッドを記録または表示するための @play.Logger.recordCaller@ の値を設定します。設定例:
+
+bc. application.log.recordCaller=true
+
+デフォルト: @false@
+
+
+h3(#application.mode). application.mode
+
+アプリケーションのモード (大文字小文字を区別します) です。設定例:
+
+bc. application.mode=prod
+
+Values:
+
+* @DEV@ - 即時リロードやその他開発のヘルプを有効にします。
+* @PROD@ - プリコンパイルや Java のソースまたはテンプレートをキャッシュします。
+
+デフォルト: @DEV@
+
+
+h3(#application.name). application.name
+
+アプリケーション名。たいていは @play new@ コマンドで設定されます。
+
+デフォルト: なし
+
+
+h3(#application.secret). application.secret
+
+暗号化に使われる秘密鍵です。たいていは @play new@ または @play secret@ コマンドで設定されます。アプリケーションを複数デプロイする場合は同じ鍵を使うようにしてください。設定例:
+
+bc. application.secret=mNuAvlsFVjeuynN4IWZxZzFOHYVagafzjruHmWTL26VISKr46rUtyGcJuX7aYx4q
+
+設定されていなければ @play.libs.Crypto.sign@ はメッセージを暗号化しません。具体的にいうと、セッションが暗号化されないということです。
+
+デフォルト: なし
+
+
+h3(#application.session.cookie). application.session.cookie
+
+セッション cookie 名です。cookie の secure 属性はデフォルトで有効ではありません。HTTPS で通信されている場合に secure 属性を true に設定します。設定例:
+
+bc. application.session.cookie=PLAY
+
+デフォルト: session は一時的な @PLAY_SESSION@ cookie に書かれます。
+
+
+h3(#application.session.httpOnly). application.session.httpOnly
+
+cookie の ‘HTTP only’ フラグを有効にします。有効にすることで XSS 攻撃の影響を受けにくくなります。設定例:
+
+bc. application.session.httpOnly=true
+
+デフォルト: @false@
+
+更に情報が必要なときは "OWASP の HttpOnly":http://www.owasp.org/index.php/HttpOnly のページを参照してください。
+
+
+h3(#application.session.maxAge). application.session.maxAge
+
+セッションタイムアウト、言い換えるとセッション cookie の最大生存期間です。設定されていない場合は、ブラウザを閉じたときにセッションが切れます。セッションの有効期間を 1 時間に設定したいときは次のようにします:
+
+bc. application.session.maxAge=1h
+
+セッションの有効期間を 1 週間にしたいときは次のようにします:
+
+bc. application.session.maxAge=7d
+
+デフォルト: ブラウザを閉じるまで
+
+
+h3(#application.session.secure). application.session.secure
+
+HTTPS 接続の cookie ベースのセッションを有効にします。設定例:
+
+bc. application.session.secure=true
+
+デフォルト: @false@
+
+
+h3(#application.session.sendOnlyIfChanged). application.session.sendOnlyIfChanged
+
+セッションに変更がない時には、セッション cookie を送らないようにします。設定例:
+
+bc. application.session.sendOnlyIfChanged=true
+
+デフォルト: @false@
+
+
+h3(#application.web_encoding). application.web_encoding
+
+Play が Web ブラウザとやり取りするときや "Web サービスクライアント":libs#WebServiceclient が使用するテキストエンコーディングです。Play はデフォルトで @UTF-8@ を使用するため、普通は設定する必要はありません。設定例:
+
+bc. application.web_encoding=ISO-8859-1
+
+デフォルト: @UTF-8@
+
+@application.web_encoding@ を変更すると HTTP ヘッダの @Content-type@ の @charset@ に影響します。また動的にレンダリングされる箇所には影響しますが、静的なコンテンツには影響 **しません**。ですから、デフォルトのレスポンスエンコーディングを変更していて、特殊文字を含む (@public/@ フォルダ内の) テキストファイルがあるときは、これらのテキストファイルのエンコーディングを指定したエンコーディングに合わせなければなりません。その他の全てのファイルは UTF-8 で保存すべきです。
+
+
+h2(#attachments). 添付ファイル
+
+
+h3(#attachments.path). attachments.path
+
+@play.db.jpa.Blob@ の内容の格納パスです。これは、絶対パス、または Play アプリケーションフォルダの中にあるフォルダへの相対パスにすることができます。設定例:
+
+bc. attachments.path=data/attachments
+
+デフォルト: @attachments@
+
+
+h2(#certificate). X509 証明書
+
+
+h3(#certificate.key.file). certificate.key.file
+
+HTTPS をサポートするための X509 証明書の秘密鍵を指定します。ファイル名は @host.key@ でなければなりません。設定例:
+
+bc. certificate.key.file=/certificates/host.key
+
+デフォルト: @conf/host.key@
+
+
+h3(#certificate.file). certificate.file
+
+HTTPS をサポートするための X509 証明書を指定します。ファイル名は @host.cert@ でなければなりません。設定例:
+
+bc. certificate.file=/certificates/host.cert
+
+デフォルト: @conf/host.cert@
+
+
+h3(#certificate.password). certificate.password
+
+パスワード保護された X509 証明書の秘密鍵のパスワードです。"certificate.key.file":#certificate.key.file で設定したものに対応するものを指定します。設定例:
+
+bc. certificate.password=secret
+
+デフォルト: @secret@
+
+
+h2(#cron). スケジューリングされたジョブ
+
+@cron.@ で始まるキーでスケジューリングされたジョブの cron 式を設定すると、<code>@play.jobs.On</code> または <code>@Every</code> アノテーションの設定値に指定したキーを使用することができます。例えば、<code>@On("cron.noon")</code> は以下の設定を参照します:
+
+bc. cron.noon=0 0 12 * * ?
+
+
+h2(#date). 日付フォーマット
+
+
+h3(#date.format). date.format
+
+@java.text.SimpleDateFormat@ パターンを使って、デフォルトの日付フォーマットを設定します。設定例:
+
+bc. date.format=dd-MM-yyyy
+
+このプロパティはテンプレート内で @${date.format()}@ がどのように日付を出力するかにも影響します。また、日付パラメータを変数にバインドするときのデフォルトの日付フォーマットも設定します。
+
+デフォルト: @yyyy-MM-dd@
+
+"application.langs":#application.langs で設定した言語ごとに異なる日付フォーマットを設定することも出来ます。設定例:
+
+bc. date.format.fr=dd-MM-yyyy
+
+
+h2(#dbconf). データベース設定
+
+h3(#db). db
+
+データベースエンジンの設定です。素早く開発用データベースをセットアップするために、一時的なインメモリデータベース (H2 インメモリデータベース) を使うには次のようにします:
+
+bc. db=mem
+
+単純なファイルに書き出すデータベース (H2 ファイルストアド) を使うには次のようにします:
+
+bc. db=fs
+
+ローカルの MySQL5 データベースを使うには次のようにします:
+
+bc. db=mysql:user:pwd@database_name
+
+アプリケーションサーバに設定されているデータソースを利用するには次のようにします:
+
+bc. db=java:/comp/env/jdbc/myDatasource@
+
+もし @Datasource@ を指定すると、データベースプラグインは @db=java:@ のパターンを検知し、デフォルトの JDBC システムを不活性化します。
+
+デフォルト: none.
+
+
+h3(#db.destroyMethod). db.destroyMethod
+
+一般的な ‘destroy’ メソッドの名前を指定します。既存のデータソースを使用するとき、アプリケーション停止時に始末する必要があることがあります。設定例:
+
+bc. db.destroyMethod=close
+
+デフォルト: なし
+
+
+h3(#db.driver). db.driver
+
+"db.url":#db.url で設定したデータベースを使うための、データベースドライバのクラス名を指定します。設定例:
+
+bc. db.driver=org.postgresql.Driver
+
+デフォルト:
+
+* @org.h2.Driver@ "db":#db が @mem@ か @fs@、または "db.url":#db.url が @jdbc:h2:mem:@ から始まっている場合
+* @com.mysql.jdbc.Driver@ "db":#db が @mysql:…@ という設定である場合
+
+h3(#db.isolation). db.isolation
+
+データベーストランザクションの隔離レベルです。設定例:
+
+bc. db.isolation=SERIALIZABLE
+
+妥当な値は @NONE@, @READ_UNCOMMITTED@, @READ_COMMITTED@, @REPEATABLE_READ@, @SERIALIZABLE@, または @java.sql.Connection.setTransactionIsolation()@ に渡される整数型の値です。すべてのデータベースがあらゆるトランザクション隔離レベルをサポートするわけではないことに注意してください。
+
+デフォルト: データベース依存、一般的には @READ_COMMITTED@
+
+h3(#db.pass). db.pass
+
+"db.url":#db.url への接続に使うデータベース接続パスワードです。
+
+デフォルト: 設定値なし、または "db":#db に @mem@ か @fs@ が設定されている場合は空文字列
+
+
+h3(#db.pool.maxIdleTimeExcessConnections). db.pool.maxIdleTimeExcessConnections
+
+"db.pool.minSize":#db.pool.minSize を超えるアイドルコネクションが ‘処分される’ までの秒数です。"c3p0 documentation":http://www.mchange.com/projects/c3p0/#maxIdleTimeExcessConnections を参照してください。
+
+デフォルト: @0@ - ‘処分されません’.
+
+
+h3(#db.pool.maxSize). db.pool.maxSize
+
+コネクションプールの最大サイズ (コネクション数) です。"c3p0 documentation":http://www.mchange.com/projects/c3p0/#maxPoolSize を参照してください。設定例:
+
+bc. db.pool.maxSize=60
+
+デフォルト: @30@
+
+
+h3(#db.pool.minSize). db.pool.minSize
+
+コネクションプールの最小サイズ (コネクション数) です。"c3p0 documentation":http://www.mchange.com/projects/c3p0/#minPoolSize を参照してください。設定例:
+
+bc. db.pool.minSize=10
+
+デフォルト: @1@
+
+
+h3(#db.pool.timeout). db.pool.timeout
+
+ミリ秒単位のコネクションプールタイムアウト時間です。"c3p0 documentation":http://www.mchange.com/projects/c3p0/#checkoutTimeout を参照してください。設定例:
+
+bc. db.pool.timeout=10000
+
+デフォルト: @5000@
+
+
+h3(#db.url). db.url
+
+"db.user":#db.user と "db.pass":#db.pass と "db.driver":#db.driver との組み合わせの完全な JDBC の設定です。設定例:
+
+bc. db.url=jdbc:postgresql:database_name
+
+デフォルト: なし
+
+
+h3(#db.user). db.user
+
+"db.url":#db.url 接続時に使われるデータベース接続ユーザ名です。
+
+デフォルト: なし、または "db":#db が @mem@ か @fs@ と設定されているときは @sa@
+
+
+h2(#evolutions). データベースエボリューションズ
+
+
+h3(#evolutions.enabled). evolutions.enabled
+
+"データベースエボリューションズ":evolutions を無効にするときに使います。
+
+bc. evolutions.enabled=false
+
+デフォルト: @true@
+
+
+h2(#test). テストランナー
+
+h3(#headlessBrowser). headlessBrowser
+
+@play auto-test@ 実行時に使用される、 HtmlUnit ヘッドレス web ブラウザの互換モードを指定します。
+
+bc. headlessBrowser=INTERNET_EXPLORER_7
+
+値:
+
+* @FIREFOX_3@
+* @FIREFOX_3_6@
+* @INTERNET_EXPLORER_6@
+* @INTERNET_EXPLORER_7@
+* @INTERNET_EXPLORER_8@
+
+デフォルト: @INTERNET_EXPLORER_8@
+
+
+h2(#hibernate). Hibernate
+
+Hibernate のプロパティを追加で指定することも出来ます。例えば、SQL コメントを有効にするには次のようにします:
+
+bc. hibernate.use_sql_comments=true
+
+h3(#hibernate.connection.datasource). hibernate.connection.datasource
+
+Hibernate のデータソース設定
+
+
+h2(#http). サーバ設定
+
+
+h3(#http.address). http.address
+
+HTTP をリッスンするアドレスです。サーバがリッスンするアドレスを制限するときに指定します。設定例:
+
+bc. http.address=127.0.0.1
+
+デフォルト: サーバが持つ全てのアドレス
+
+
+h3(#http.cacheControl). http.cacheControl
+
+静的ファイルを制御するための HTTP レスポンスヘッダ: 秒単位でデフォルトの最大期間を設定すると、ユーザのブラウザにページをどれだけの期間キャッシュすべきかを伝えます。この値は @prod@ モードの時のみ読み取られ、 @dev@ モードではキャッシュは無効になります。例えば、 @no-cache@ を送りたいときは次のようにします:
+
+bc. http.cacheControl=0
+
+デフォルト: @3600@ - キャッシュの有効期限を 1時間に設定します。
+
+
+h3(#http.exposePlayServer). http.exposePlayServer
+
+HTTP サーバを Play と特定する HTTP レスポンスヘッダを無効にします。設定例:
+
+bc. http.exposePlayServer=false
+
+デフォルト: @true@
+
+
+h3(#http.path). http.path
+
+サーバ上でアプリケーションが動作する URL パス: Play アプリケーションをドメインのルートに置きたくないときに使います。このパラメータは WAR としてデプロイしたときには効果がありません。なぜならパスはアプリケーションサーバにハンドリングされるからです。設定例:
+
+bc. http.path=/myapp/
+
+デフォルト: @/@
+
+
+h3(#http.port). http.port
+
+HTTP サーバがリッスンするポート
+
+デフォルト: @9000@
+
+
+h3(#http.proxyHost). http.proxyHost
+
+Web サービスをリクエストする際に使用するプロキシサーバです。設定例:
+
+bc. http.proxyHost=localhost
+
+デフォルト: @http.proxyHost@ システムプロパティ
+
+
+h3(#http.proxyPassword). http.proxyPassword
+
+Web サービスをリクエストする際に使用するプロキシのパスワード
+
+デフォルト: @http.proxyPassword@ システムプロパティ
+
+
+h3(#http.proxyPort). http.proxyPort
+
+Web サービスをリクエストする際に使用するプロキシのポートです。設定例:
+
+bc. http.proxyPort=3128
+
+デフォルト: @http.proxyPort@ システムプロパティ
+
+
+h3(#http.proxyUser). http.proxyUser
+
+Web サービスをリクエストする際に使用するプロキシのユーザ
+
+デフォルト: @http.proxyUser@ システムプロパティ
+
+
+
+h3(#http.nonProxyHosts). http.nonProxyHosts
+
+プロキシサーバを通さずに直接接続するべきホストを示します。
+ホストを @|@ で区切ったリストを値とすることができるほか、ワイルドカード文字 @*@ をマッチングに使うことができます。
+
+設定例:
+
+bc. http.nonProxyHosts=localhost|*.example.com
+
+デフォルト: @http.nonProxyHosts@ システムプロパティ
+
+
+
+h3(#http.useETag). http.useETag
+
+有効にすると Play はエンティティタグを自動的に生成し、必要なときに 304 を送ります。例えば、エンティティタグの利用を停止するには次のようにします:
+
+bc. http.useETag=false
+
+デフォルト: @true@
+
+
+h3(#http.userAgent). http.userAgent
+
+Web サービスをリクエストする際に送るカスタムの @USER_AGENT@ ヘッダの値です。設定例:
+
+bc. http.userAgent=myApp 1.0
+
+デフォルト: none.
+
+
+h3(#https.port). https.port
+
+HTTPS コネクタを有効化し、指定したポートでリッスンします。設定例:
+
+bc. https.port=9443
+
+デフォルト: none - HTTPS の設定なし
+
+
+h2(#java). Java ソース
+
+
+h3(#java.source). java.source
+
+Java ソースレベルです。これは @java.version@ システムプロパティをオーバーライドします。設定例:
+
+bc. java.source=1.6
+
+Values: @1.5@, @1.6@, @1.7@ (experimental).
+
+デフォルト: @1.5@
+
+
+h2(#jpa). JPA
+
+
+h3(#jpa.dialect). jpa.dialect
+
+使用するカスタムの JPA ダイアレクトをここで指定します。設定例:
+
+bc. jpa.dialect=org.hibernate.dialect.PostgreSQLDialect
+
+デフォルト: Play は "db.driver":#db.driver の設定に基づいてダイアレクトを推測します。
+
+
+h3(#jpa.ddl). jpa.ddl
+
+使用する DDL 生成パターンを指定します。例えば、自動データベース構造更新を有効にするには次のようにします:
+
+bc. jpa.ddl=create-drop
+
+デフォルト: @update@ (@dev@ モード) または @none@ (@prod@ モード).
+
+
+h3(#jpa.debugSQL). jpa.debugSQL
+
+SQL 文をデバッグ (DEBUG レベルでロギング) します。設定例:
+
+bc. jpa.debugSQL=true
+
+デフォルト: @false@
+
+
+h3(#jpa.entities). jpa.entities
+
+追加でロードする JPA エンティティクラス名のカンマ区切りのリストです。分けられた JAR ファイル内のモデルクラスのように @models@ パッケージに入っていない追加のエンティティがある場合に便利です。設定例:
+
+bc. org.example.model.Person, org.example.model.Organisation
+
+デフォルト: なし
+
+
+h3(#jpa.mapping-file). jpa.mapping-file
+
+JPA マッピングファイル
+
+デフォルト: なし
+
+
+h2(#jpda). JVM
+
+
+h3(#jpda.port). jpda.port
+
+アプリケーションがデバッグモードで動作しているときに JPDA に使われるポートを定義します。設定例:
+
+デフォルト: @8000@
+
+
+h2(#keystore). キーストア
+
+
+h3(#keystore.algorithm). keystore.algorithm
+
+JDK セキュリティ API 標準アルゴリズム名です。これは "keystore.file":#keystore.file の設定とともに使われます。
+
+bc. keystore.algorithm=pkcs12
+
+Values - JDK セキュリティ API の ‘標準名’:
+
+* @jceks@ (‘SunJCE’ プロバイダ)
+* @jks@ (‘SUN" プロバイダ)
+* @pkcs12@
+
+デフォルト: @JKS@
+
+
+h3(#keystore.file). keystore.file
+
+HTTPS をサポートするための証明書を指定します。ファイル名は @certificate.jks@ にすべきです。設定例:
+
+bc. keystore.file=conf/certificate.jks
+
+
+h3(#keystore.password). keystore.password
+
+"keystore.file":#keystore.file の設定を使うためのキーストア設定です。
+
+bc. keystore.password=secret
+
+デフォルト: @secret@
+
+
+h2(#memcachedconfig). Memcached
+
+
+h3(#memcached). memcached
+
+"Memcached":http://www.danga.com/memcached/ を有効にします。Memcached を設定しなければ、Play は JVM ヒープにデータを格納するスタンドアロンのキャッシュを使います。
+
+bc. memcached=enabled
+
+デフォルト: @disabled@
+
+関連項目: "キャッシュを使う":cache.
+
+
+h3(#memcached.host). memcached.host
+
+memcached ホストを指定します。設定例:
+
+bc. memcached.host=127.0.0.1:11211
+
+デフォルト: @127.0.0.1:11211@
+
+分散キャッシュを構築するために複数のホストを指定することも出来ます。設定例:
+
+bc. memcached.1.host=127.0.0.1:11211
+memcached.2.host=127.0.0.1:11212
+
+
+h2(#mimetype). カスタム MIME タイプ
+
+MIME タイプを追加して定義できます。設定例:
+
+bc. mimetype.xpi=application/x-xpinstall
+
+
+h2(#webserviceconfig). Web サービス
+
+h3(#webservice). webservice
+
+Web サービスの実装クラス名、またはビルトインの実装。設定例:
+
+bc. webservice=urlfetch
+
+値:
+
+* @urlfetch@ - JDK の内部実装
+* @async@ - 非同期の Http クライアント
+* @play.libs.WS.WSImpl@ の実装クラス名
+
+デフォルト: @async@ - 非同期の Http クライアント
+
+
+h2(#mail). メール
+
+
+h3(#mail.debug). mail.debug
+
+SMTP トランザクションのロギングを有効にします。内部では Play は SMTP 通信をするために JavaMail を使っています。
+
+bc. mail.debug=true
+
+デフォルト: @false@
+
+
+h3(#mail.smtp). mail.smtp
+
+メールの設定キーです。
+
+デフォルト: @mock@ - モックの Mailer を使います
+
+関連項目: "SMTP の設定":emails#smtp.
+
+
+h3(#mail.smtp.authenticator). mail.smtp.authenticator
+
+カスタムの SMTP 認証 (@javax.mail.Authenticator@) 実装のクラス名です。
+
+デフォルト: なし
+
+
+h3(#mail.smtp.channel). mail.smtp.channel
+
+暗号化された経路で e メールを送信する方法は二通りあり、このプロパティで方法を選択できます。値は以下の通りです:
+
+* @clear@ - 暗号化なし
+* @ssl@ - SMTP-over-SSL (SMTPS) コネクタ; 465 番ポートでリッスンしている SSL ソケットです。
+* @starttls@ - 使用するサーバが @starttls@ コマンド (参考: "RFC 2487":http://www.apps.ietf.org/rfc/rfc2487.html) に対応していれば、SSL/TLS に切り替わる 25 番ポートの接続です。
+
+デフォルト: @clear@
+
+
+h3(#mail.smtp.host). mail.smtp.host
+
+外向きのメールサーバです。設定例:
+
+bc. mail.smtp.host=127.0.0.1
+
+GMail の SMTP サーバを使うには次のようにします:
+
+bc. mail.smtp.host=smtp.gmail.com
+
+デフォルト: @localhost@
+
+
+h3(#mail.smtp.localhost). mail.smtp.localhost
+
+SMTP コマンドで使用されるローカルホスト名
+
+デフォルト: なし - Java Mail のデフォルト値を使います。
+
+
+h3(#mail.smtp.pass). mail.smtp.pass
+
+SMTP サーバのパスワードです。"mail.smtp.host":#mail.smtp.host のものです。例えば GMail のパスワードです。
+
+デフォルト: なし
+
+
+h3(#mail.smtp.port). mail.smtp.port
+
+接続先の SMTP サーバのポート番号です。デフォルト値をオーバーライドするために使います。設定例:
+
+bc. mail.smtp.port=2500
+
+デフォルト:
+
+* @25@ "mail.smtp.channel":#mail.smtp.channel に @clear@ または @starttls@ がセットされているとき
+* @465@ "mail.smtp.channel":#mail.smtp.channel に @ssl@ がセットされているとき
+
+
+h3(#mail.smtp.protocol). mail.smtp.protocol
+
+Sets whether to use SSL. Values:
+SSL を使うかどうかを設定します。値は以下のとおりです:
+
+* @smtp@
+* @smtps@
+
+デフォルト: @smtp@
+
+
+h3(#mail.smtp.socketFactory.class). mail.smtp.socketFactory.class
+
+JavaMail で SSL 接続を使うとき、接続先のサーバの証明書がルート証明書によって署名されていなければ、デフォルトでは接続を切断します。具体的には自己署名の証明書を使っているときです。Play はデフォルトでルート証明書のチェックをスキップします。このプロパティを使って振る舞いを制御できます。
+
+
+h3(#mail.smtp.user). mail.smtp.user
+
+SMTP サーバのユーザ名です。"mail.smtp.host":#mail.smtp.host のものです。例えば GMail のユーザ名です。
+
+デフォルト: none.
+
+
+h2(#play). Play run-time
+
+
+h3(#play.bytecodeCache). play.bytecodeCache
+
+@dev@ モードでバイトコードキャッシュを無効にするときに使用します。 @prod@ モードには影響しません。
+
+bc. play.bytecodeCache=false
+
+デフォルト: @true@
+
+
+h3(#play.editor). play.editor
+
+エラーページからファイルを開きます。使用しているテキストエディタが URL からファイルを開くことが出来れば、Play はエラーページからファイルへ動的にリンクします。Textmate での具体例は以下のとおりです:
+
+bc. play.editor=txmt://open?url=file://%s&line=%s
+
+
+h3(#play.jobs.pool). play.jobs.pool
+
+ジョブプールのサイズです。設定例:
+
+bc. play.jobs.pool=20
+
+デフォルト: @10@
+
+
+h3(#play.netty.clientAuth). play.netty.clientAuth
+
+@javax.net.ssl.SSLEngine@ のクライアント認証を設定します。設定例:
+
+bc. play.netty.clientAuth=need
+
+値:
+
+* @want@ - サーバはクライアント認証を _要求します_
+* @need@ - サーバはクライアント認証を _必要とします_
+* @none@ - クライアント認証不要
+
+デフォルト: @none@
+
+
+h3(#play.netty.maxContentLength). play.netty.maxContentLength
+
+HTTP サーバがレスポンスとして返すコンテンツのバイト単位の最大長です。
+
+デフォルト: なし - 制限なし
+
+
+h3(#play.pool). play.pool
+
+実行プールサイズです。この値はできるだけ小さく抑えてください。この値を 1 スレッドに設定すると全てのリクエストは直列に処理されます (デバッグ目的には非常に有用です)。
+
+bc. play.pool=10
+
+デフォルト: @1@ (@dev@ モード), プロセッサ数 + 1 (@prod@ モード).
+
+
+h3(#play.tmp). play.tmp
+
+一時ファイルを格納するフォルダです。設定例:
+
+bc. play.tmp=/tmp/play
+
+値:
+
+* 絶対パス
+* アプリケーションディレクトリからの相対パス
+* @none@ 一時ディレクトリが使われないようにします
+
+デフォルト: @tmp@
+
+
+h2(#ssl). SSL
+
+関連項目: "https.port":#https.port.
+
+
+h3(#ssl.KeyManagerFactory.algorithm). ssl.KeyManagerFactory.algorithm
+
+"keystore.file":#keystore.file の設定に使用する Java Secure Socket Extension (JSSE) 信頼管理アルゴリズムの標準名です。
+
+bc. ssl.KeyManagerFactory.algorithm=SunX509
+
+デフォルト: @SunX509@
+
+
+h2(#trustmanager). trustmanager
+
+
+h3(#trustmanager.algorithm). trustmanager.algorithm
+
+"X509 証明書":#certificate と "キーストア":#keystore の設定で使用する JDK セキュリティ API の標準アルゴリズム名です。
+
+bc. trustmanager.algorithm=pkcs12
+
+値 - JDK セキュリティ API の ‘標準名’:
+
+* @jceks@ (‘SunJCE’ プロバイダ)
+* @jks@ (‘SUN" プロバイダ)
+* @pkcs12@
+
+デフォルト: @JKS@
+
+bc. play.netty.clientAuth
+
+値
+
+* @want@ 受け入れたサーバーモードの SSLSockets が、クライアント認証を要求するように初期設定するかどうかを制御します。
+* @need@ 受け入れたサーバーモードの SSLSockets で、クライアント認証が必須とされるように初期設定するかどうかを制御します。
+* @none@ 上記以外
+
+デフォルト: @none@
+
+h2(#upload). ファイルアップロード
+
+h3(#upload.threshold). upload.threshold
+
+ディスクに書き出されるファイルのアップロード時のバイト単位でのしきい値です。 @org.apache.commons.io.output.DeferredFileOutputStream@ に使われます。設定例:
+
+bc. upload.threshold=20480
+
+デフォルト: @10240@
+
+
+h2(#xforwarded). プロキシ転送
+
+h3(#XForwardedHost). XForwardedHost
+
+@X-Forwarded-Host@ HTTP ヘッダ値を上書きします。このヘッダ値はプロキシサーバとともに使われ、クライアントが要求した元のホストを保持しています。
+
+デフォルト: @X-Forwarded-Host@ HTTP ヘッダ値
+
+
+h3(#XForwardedProto). XForwardedProto
+
+@X-Forwarded-Proto@ と @X-Forwarded-SSL@ HTTP ヘッダ値を上書きすることで、プロキシへのリクエストを SSL だと設定します。このヘッダ値はクライアントが要求した元のプロトコルを保持します。設定例:
+
+bc. XForwardedProto=https
+
+
+h3(#XForwardedSupport). XForwardedSupport
+
+@X-Forwarded-For@ HTTP リクエストヘッダ値として許可された IP アドレスのカンマ区切りのリストです。プロキシサーバが @X-Forwarded-For@ リクエストヘッダをセットする場合、ローカルアドレスを制限するために使用します。
+
+デフォルト: @127.0.0.1@
809 documentation/manual_ja/controllers.textile
View
@@ -0,0 +1,809 @@
+h1. コントローラ
+
+ビジネスロジックはドメインモデル層で管理されます。クライアント (通常は web ブラウザ) が直接このコードを呼び出すことができないことから、ドメインオブジェクトの機能性は URI によって表されたリソースとして公開されます。
+
+クライアントは、HTTP プロトコルによって提供された統一的な API を使用して、これらのリソースと、暗黙的にその下にあるビジネスロジックを操作します。しかし、ドメインオブジェクトとリソースのマッピングは一対一ではありません: 粒度は異なるレベルで表現され、あるリソースは仮想化されたものかもしれませんし、あるリソースは別名が定義されているかもしれません…
+
+これは、まさにコントローラ層によって果たされる役割です: ドメインモデルオブジェクトとトランスポート層イベントの間の **接着剤** を提供します。モデル層においては、モデルオブジェクトに容易にアクセスし変更するために、コントローラは純粋な Java で書かれます。HTTP インタフェースのように、コントローラは手続き的で、リクエスト/レスポンス指向です。
+
+コントローラ 層 は HTTP とドメインモデルの間の **インピーダンスミスマッチ** を減少させます。
+
+p(note). **注意**
+
+異なる戦略をもった異なるアーキテクチャモデルがあります。いくつかのプロトコルはドメインモデルオブジェクトに直接アクセスします。これは、EJB や CORBA プロトコルによく見られます。これらの場合、そのアーキテクチャスタイルは、RPC (Remote Procedure Call) を使います。これらのコミュニケーションスタイルは、web アーキテクチャとほとんど互換性がありません。
+
+SOAP のようないくつかの技術は Web を通してドメインモデルオブジェクトへのアクセスをていきょうします。しかし、SOAP はただのRPC スタイルプロトコルであり、この場合、HTTP はトランスポートプロトコルとして使用されます。アプリケーションプロトコルではありません。
+
+web の原則は基本的にオブジェクト指向ではありません。そのため、お気に入りの言語に HTTP を適合させる層が必要になります。
+
+
+h2. <a name="overview">コントローラの概要</a>
+
+コントローラは Java のクラスであり、 @controllers@ パッケージで管理される @play.mvc.Controller@ のサブクラスです。
+
+コントローラはこのようなものになります:
+
+bc. package controllers;
+
+import models.Client;
+import play.mvc.Controller;
+
+public class Clients extends Controller {
+
+ public static void show(Long id) {
+ Client client = Client.findById(id);
+ render(client);
+ }
+
+ public static void delete(Long id) {
+ Client client = Client.findById(id);
+ client.delete();
+ }
+
+}
+
+コントローラの public かつ static なそれぞれのメソッドはアクションと呼ばれます。アクションメソッドのシグネチャは以下の通りです:
+
+bc. public static void action_name(params...);
+
+アクションメソッドのシグネチャに引数を定義できます。これらのパラメタは、フレームワークによって対応する HTTP パラメタから自動的に解決されます。
+
+通常、アクションメソッドは return 構文を持ちません。アクションメソッドは **result** メソッドの起動によって終了します。今回の例では、テンプレートを実行して表示する @render(…)@ が result メソッドです。
+
+h2. <a name="params">HTTP パラメータの取得</a>
+
+HTTP リクエストはデータを含んでいます。以下のようにしてこのデータを抽出することができます:
+
+* URI パス: @/clients/1541@ という URI パターンにおいて、1541 が動的な部分です。
+* クエリ文字列: @/clients?id=1541@
+* リクエスト本文: リクエストが HTML フォームから送信される場合、そのリクエスト本文には @x-www-urlform-encoded@ としてエンコードされたフォームデータを含んでいます。
+
+いずれの場合でも、Play はデータを抽出して、すべての HTTP パラメータを含む Map<String, String[]> を構築します。このマップのキーはパラメータ名です。パラメータ名は以下のようにして導出されます。
+
+* (ルーティングで指定された) URI の動的部分の名前
+* クエリ文字列から取得される名前-値のペアの名前の部分
+* エンコードされた本文の内容
+
+h3. <a name="paramsmap">パラメータマップの使い方</a>
+
+@params@ オブジェクトはすべてのコントローラクラスで利用できます (スーパークラス @play.mvc.Controller@ で定義されています) 。このオブジェクトは、現在のリクエストから見つけられるすべての HTTP パラメータを含んでいます。
+
+例えば:
+
+bc. public static void show() {
+ String id = params.get("id");
+ String[] names = params.getAll("names");
+}
+
+Play に型変換を指示することもできます:
+
+bc. public static void show() {
+ Long id = params.get("id", Long.class);
+}
+
+でも、ちょっと待ってください。もっと良い方法があります:)
+
+h3. <a name="methodsignature">アクションメソッドのシグネチャ</a>
+
+アクションメソッドのシグネチャから HTTP パラメータを直接検索することができます。Java 引数の名前は HTTP パラメータのものと同じであるに違いありません。
+
+例えば、このリクエストでは:
+
+bc. /clients?id=1451
+
+アクションメソッドは、シグネチャにおいて @id@ 引数を宣言することによって、 @id@ パラメータの値を検索することができます:
+
+bc. public static void show(String id) {
+ System.out.println(id);
+}
+
+String 以外の Java の型も使えます。この場合、フレームワークはパラメータの値を正しい Java 型にキャストしようとします:
+
+bc. public static void show(Long id) {
+ System.out.println(id);
+}
+
+パラメータが多値である場合は、配列引数を宣言することができます:
+
+bc. public static void show(Long[] id) {
+ for(String anId : id) {
+ System.out.println(anid);
+ }
+}
+
+コレクションも宣言することができます:
+
+bc. public static void show(List<Long> id) {
+ for(String anId : id) {
+ System.out.println(anid);
+ }
+}
+
+p(note). **例外**
+
+アクションメソッド引数に対応する HTTP パラメータが見つからない場合、対応するメソッド引数はデフォルト値 (通常、オブジェクト型は null、基本データ型は 0) に設定されます。値が見つかっても、要求された Java 型に適切にキャストできない場合、バリデーションエラーのコレクションにエラーが追加され、デフォルト値が設定されます。
+
+h2. <a name="binding">HTTP と Java の高度な紐付け</a>
+
+h3. <a name="simpletypes">シンプルな型</a>
+
+すべての基本データ型と、そして、一般的な Java の型は自動的に紐付けられます:
+
+@int@, @long@, @boolean@, @char@, @byte@, @float@, @double@, @Integer@, @Long@, @Boolean@, @Char@, @String@, @Byte@, @Float@, @Double@.
+
+HTTP リクエスト中にパラメータが見つからないか、または自動変換に失敗した場合、オブジェクト型には null、基本データ型にはそれらのデフォルト値が設定されることに注意してください。
+
+h3. <a name="date">日付</a>
+
+日付の文字列表現が以下のパターンのいずれか 1 つにマッチする場合、自動的に日付オブジェクトに紐付けられます:
+
+* yyyy-MM-dd'T'hh:mm:ss'Z' // ISO8601 + timezone
+* yyyy-MM-dd'T'hh:mm:ss" // ISO8601
+* yyyy-MM-dd
+* yyyyMMdd'T'hhmmss
+* yyyyMMddhhmmss
+* dd'/'MM'/'yyyy
+* dd-MM-yyyy
+* ddMMyyyy
+* MMddyy
+* MM-dd-yy
+* MM'/'dd'/'yy
+
+<code>@As</code> アノテーションを使って日付フォーマットを指定することができます。
+
+例えば:
+
+bc. archives?from=21/12/1980
+
+bc. public static void articlesSince(@As("dd/MM/yyyy") Date from) {
+ List<Article> articles = Article.findBy("date >= ?", from);
+ render(articles);
+}
+
+言語によって日付フォーマットを最適化することもできます。例えば:
+
+bc. public static void articlesSince(@As(lang={"fr,de","*"},
+ value={"dd-MM-yyyy","MM-dd-yyyy"}) Date from) {
+ List<Article> articles = Article.findBy("date >= ?", from);
+ render(articles);
+}
+
+この例の場合、フランス語とドイツ語には日付フォーマットに @dd-MM-yyyy@ を指定し、その他の言語には @MM-dd-yyyy@ を指定しています。言語の値をカンマで区切れることに注意してください。言語パラメータの数と値パラメータの数を合わせることが重要です。
+
+<code>@As</code> アノテーションが指定されていない場合、Play! はロケールに従ったデフォルトの日付フォーマットを使用します。デフォルトで使用する日付フォーマットは "date.format の設定":configuration#date.format で指定します。
+
+
+h3. <a name="calendar">カレンダ</a>
+
+Play がロケールに従って Calendar オブジェクトを選択する場合を除いて、カレンダの紐付けは日付とまるっきり同じように動作します。 <code>@Bind</code> アノテーションを使用することもできます。
+
+h3. <a name="file">ファイル</a>
+
+Play によるファイルアップロードは簡単です。 @multipart/form-data@ エンコードされたリクエストを使ってサーバにファイルをポストしたら、 @java.io.File@ 型を使ってファイルオブジェクトを取得します:
+
+bc. public static void create(String comment, File attachment) {
+ String s3Key = S3.post(attachment);
+ Document doc = new Document(comment, s3Key);
+ doc.save();
+ show(doc.id);
+}
+
+作成されたファイルは、元のファイルと同じ名前になります。ファイルは一時ディレクトリに保存されて、リクエストの完了時に削除されます。このため、作成されたファイルは安全なディレクトリにコピーしなければなりません。そうでなければファイルは無くなってしまいます。
+
+通常、アップロードされたファイルの MIME タイプは HTTP リクエストの @Content-type@ ヘッダで指定されます。しかし、一般的でない種類のファイルが web ブラウザからアップロードされた場合、この MIME タイプの指定は行われない場合があります。このような場合、 @play.libs.MimeTypes@ クラスを使ってファイル名の拡張子を MIME タイプにマッピングすることができます。
+
+bc. String mimeType = MimeTypes.getContentType(attachment.getName());
+
+@play.libs.MimeTypes@ クラスは、与えられたファイル名拡張子の MIME タイプを @$PLAY_HOME/framework/src/play/libs/mime-types.properties@ の中から探します。
+
+"カスタム MIME タイプ設定":configuration#mimetype を使って独自の型をアプリケーションの @conf/application.conf@ ファイルに追加することもできます。
+
+
+h3. <a name="array">サポートされた型の配列またはコレクション</a>
+
+すべてのサポートされた型は配列またはオブジェクトのコレクションとして取得することができます:
+
+bc. public static void show(Long[] id) {
+ …
+}
+
+または:
+
+bc. public static void show(List<Long> id) {
+ …
+}
+
+または:
+
+bc. public static void show(Set<Long> id) {
+ …
+}
+
+Play は、以下のような特別なケースの Map<String, String> のバインディングも取り扱います:
+
+bc. public static void show(Map<String, String> client) {
+ …
+}
+
+
+クエリ文字列は以下のようになります:
+
+bc. ?client.name=John&client.phone=111-1111&client.phone=222-2222
+
+クライアントの変数は要素がふたつのマップにバインドされます。ひとつ目の要素はキーが @name@ で値が @John@, そしてふたつ目の要素はキーが @phone@ で値が @111-1111, 222-2222@ です。
+
+h3. <a name="pojo">POJO オブジェクトの紐付け</a>
+
+Play は簡単な命名規約ルールを使用することで、どんなモデルクラスでも自動的に紐付けることができます。
+
+bc. public static void create(Client client ) {
+ client.save();
+ show(client);
+}
+
+このアクションを使って client を作るクエリ文字列は次のようになるでしょう:
+
+bc. ?client.name=Zenexity&client.email=contact@zenexity.fr
+
+Play は Client インスタンスを作成し、HTTP パラメータの名前を Client オブジェクトのプロパティに解決します。解決できないパラメータ名は安全に無視されます。型のミスマッチも安全に無視されます。
+
+パラメータの紐付けは再帰的に行われるので、完全なオブジェクトグラフを扱うことができます:
+
+bc. ?client.name=Zenexity
+&client.address.street=64+rue+taitbout
+&client.address.zip=75009
+&client.address.country=France
+
+モデルオブジェクトのリストを更新するには、配列記法とオブジェクトを参照する ID を使用してください。例えば、Client モデルが @List Customer customers@ として宣言された Customer モデルのリストを持つと想像してください。Customer のリストを更新するために、以下のようなクエリ文字列を提供するでしょう:
+
+bc. ?client.customers[0].id=123
+&client.customers[1].id=456
+&client.customers[2].id=789
+
+
+h2. <a name="objectbinding">JPA オブジェクトの紐付け</a>
+
+HTTP と Java の紐付けを使って、自動的に JPA オブジェクトを紐付けることができます。
+
+HTTP パラメータ中に @user.id@ フィールドを提供することできます。Play は @id@ フィールドを見つけると、user を編集する前に、データベースからマッチするインスタンスをロードします。そして、HTTP リクエストで提供された他のパラメータを適用します。このため、直接 user を保存することができます。
+
+bc. public static void save(User user) {
+ user.save(); // ok with 1.0.1
+}
+
+POJO マッピングの動きと同じやり方で JPA バインディングを使って完全なオブジェクトグラフを変更することができますが、変更するサブオブジェクトごとに ID を供給しなければなりません:
+
+bc. user.id = 1
+&user.name=morten
+&user.address.id=34
+&user.address.street=MyStreet
+
+h2. <a name="custombinding">カスタムバインディング</a>
+
+バインディングシステムはより多くのカスタマイズをサポートするようになりました。
+
+h3. <a name="as">@play.data.binding.As</a>
+
+最初に紹介するのは、文脈的にバインディングを構成する新しい <code>@play.data.binding.As</code> アノテーションです。これは例えば、 @DateBinder@ によって使用される日付のフォーマットを指定するために使います:
+
+bc. public static void update(@As("dd/MM/yyyy") Date updatedAt) {
+ …
+}
+
+この <code>@As</code> アノテーションは国際化もサポートします。これは、ロケールごとに特定のアノテーションを提供できることを意味しています:
+
+bc. public static void update(
+ @As(
+ lang={"fr,de","en","*"},
+ value={"dd/MM/yyyy","dd-MM-yyyy","MM-dd-yy"}
+ )
+ Date updatedAt
+ ) {
+ …
+}
+
+この <code>@As</code> アノテーションは、これをサポートするすべてのバインダと共に動作します。以下は、 @ListBinder@ を使用する例です:
+
+bc. public static void update(@As(",") List<String> items) {
+ …
+}
+
+このバインダは、単純にカンマで分けられた @String@ を @List@ にバイドします。
+
+h3. <a name="nobinding">@play.data.binding.NoBinding</a>
+
+新たに追加された <code>@play.data.binding.NoBinding</code> は、バインド非対象フィールドをマークし、潜在的なセキュリティ問題を解決します。以下に例を示します:
+
+bc. public class User extends Model {
+ @NoBinding("profile") public boolean isAdmin;
+ @As("dd, MM yyyy") Date birthDate;
+ public String name;
+}
+
+public static void editProfile(@As("profile") User user) {
+ …
+}
+
+このようにすると、例え悪意あるユーザが偽のフォームから @user.isAdmin=true@ というフィールドを含めてポストしたとしても、 @isAdmin@ フィールドは決して @editProfile@ アクションからはバインドされません。
+
+h3. <a name="typebinder">play.data.binding.TypeBinder</a>
+
+*@As* アノテーションを使って完全に独自のバインダを定義することができます。独自のバインダは、プロジェクト内にて @TypeBinder@ のサブクラスとして定義されます。以下に例を示します:
+
+bc. public class MyCustomStringBinder implements TypeBinder<String> {
+
+ public Object bind(String name, Annotation[] anns, String value,
+ Class clazz) {
+ return "!!" + value + "!!";
+ }
+}
+
+以下のようにして、いずれのアクションにおいてもこのバインダを使用することができます:
+
+bc. public static void anyAction(@As(binder=MyCustomStringBinder.class)
+String name) {
+ …
+}
+
+h3. <a name="global">@play.data.binding.Global</a>
+
+対応する型にだけ適用されるグローバルなカスタムバインダを定義することもできます。例えば、以下のようにして @java.awt.Point@ クラスにバインドできるバインダを定義することができます:
+
+bc. @Global
+public class PointBinder implements TypeBinder<Point> {
+
+ public Object bind(String name, Annotation[] anns, String value,
+ Class class) {
+ String[] values = value.split(",");
+ return new Point(
+ Integer.parseInt(values[0]),
+ Integer.parseInt(values[1])
+ );
+ }
+}
+
+見てのとおり、グローバルバインダは *@play.data.binding.Global* でアノテーションされた古典的なバインダです。外部モジュールは再利用可能な拡張バインダを定義することで、プロジェクトにバインダを提供することができます。
+
+
+h2. <a name="result">戻り値の型</a>
+
+アクションメソッドは、HTTP レスポンスを生成しなければなりません。HTTP レスポンスを生成するもっとも簡単な方法は、Result オブジェクトを発行することです。Result オブジェクトが発行されると、通常の実行フローは中断され、メソッドはリターンされます。
+
+例えば:
+
+bc. public static void show(Long id) {
+ Client client = Client.findById(id);
+ render(client);
+ System.out.println("This message will never be displayed !");
+}
+
+@render(…)@ メソッドは Result オブジェクトを発行し、以降のメソッドは実行しません。
+
+h3. <a name="text">テキスト内容の返却</a>
+
+@renderText(…)@ メソッドは基本的な HTTP レスポンスに何らかのテキストを直接書き込むシンプルな Result イベントを発行します。
+
+例えば:
+
+bc. public static void countUnreadMessages() {
+ Integer unreadMessages = MessagesBox.countUnreadMessages();
+ renderText(unreadMessages);
+}
+
+Java 標準のフォーマット構文を使ってテキストメッセージをフォーマットすることができます:
+
+bc. public static void countUnreadMessages() {
+ Integer unreadMessages = MessagesBox.countUnreadMessages();
+ renderText("There are %s unread messages", unreadMessages);
+}
+
+h3. <a name="renderjson">JSON 文字列の返却</a>
+
+Play には @renderJSON(…)@ メソッドを使ってシンプルに JSON 文字列を返却するメソッドが備わっています。これらのメソッドは JSON 文字列を返却し、レスポンスのコンテントタイプに @application/json@ を設定します。
+
+自分で JSON 文字列を指定するか、または @GsonBuilder@ によってシリアライズされる @Object@ を渡すことができます。
+
+例えば:
+
+bc. public static void countUnreadMessages() {
+ Integer unreadMessages = MessagesBox.countUnreadMessages();
+ renderJSON("{\"messages\": &q