やまろうのJavaなわけ 2006/01 Vol.44 java.sql.DatabaseMetaDataでDBメタ情報からSQLを自動生成する java.sql.DatabaseMetaDataを使うとDBのメタ情報(テーブル定義情報等)を 取得することが出来ます。テーブル名や列名、属性、長さ等です。 これらを元にSQL文を生成したいと思います。 */package tool.db; import java.io.FileWriter; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; /** * JDBCでDBに接続してメタ情報を取得し、SQL文を生成してファイルに出力する。 * SQL文はSELECT(無条件 & 主キーを条件)、INSERT、UPDATE(主キーを条件)、 * DELETE(主キーを条件) * @author yamarou */ public class SQLGeneretor { public static void main(String[] args) throws Exception { System.out.println("処理開始"); PrintWriter out = new PrintWriter(new FileWriter("c:/TEMP/sql.txt")); String driverName = "COM.ibm.db2.jdbc.app.DB2Driver"; String url = "jdbc:db2:YAMAROUDB"; String user = "db2admin"; String password = "db2admin"; String schem = "SCHEM01"; ArrayList list = loadDBInfo(driverName, url, user, password, schem); for (int i = 0; i < list.size(); i++) { TableVO table = (TableVO) list.get(i); String tableID4Java = table.getName(); tableID4Java = tableID4Java.substring(0, 1) + tableID4Java.substring(1).toLowerCase(); String sql = "SELECT "; String columnNames = ""; for (Iterator iter = table.getColumns().iterator(); iter.hasNext(); ) { String column = (String) iter.next(); sql += column + ","; columnNames += column + ","; } sql = sql.substring(0, sql.length() - 1); sql += " FROM " + schem + "." + table.getName(); columnNames = columnNames.substring(0, columnNames.length() - 1); sql += " WHERE "; String where = ""; for (Iterator iter = table.getPrimaryKeys().iterator(); iter.hasNext(); ) { String column = (String) iter.next(); sql += column + "=? AND "; where += column + "=? AND "; } sql = sql.substring(0, sql.length() - 5); out.println(sql); try { where = where.substring(0, where.length() - 5); } catch (StringIndexOutOfBoundsException e) { } sql = "INSERT INTO " + schem + "." + table.getName() + "("; for (Iterator iter = table.getColumns().iterator(); iter.hasNext(); ) { String column = (String) iter.next(); sql += column + ","; } sql = sql.substring(0, sql.length() - 1); sql += ") VALUES("; String values = ""; for (Iterator iter = table.getColumns().iterator(); iter.hasNext(); ) { String column = (String) iter.next(); sql += "?,"; if (column.equals("RCRD_CRTS")) { values += "CURRENT TIMESTAMP,"; } else if (column.equals("ROW_UPDTS_DBS")) { values += "CURRENT TIMESTAMP,"; } else { values += "?,"; } } sql = sql.substring(0, sql.length() - 1) + ")"; out.println(sql); values = values.substring(0, values.length() - 1); sql = "DELETE FROM " + schem + "." + table.getName() + " WHERE "; for (Iterator iter = table.getPrimaryKeys().iterator(); iter.hasNext(); ) { String column = (String) iter.next(); sql += column + "=? AND "; } sql = sql.substring(0, sql.length() - 5); out.println(sql); sql = "UPDATE " + schem + "." + table.getName() + " SET "; String columnNamesAndParameters = ""; for (Iterator iter = table.getColumns().iterator(); iter.hasNext(); ) { String column = (String) iter.next(); sql += column + "=?,"; if (column.equals("ROW_UPDTS_DBS")) { columnNamesAndParameters += column + "=CURRENT TIMESTAMP,"; } else if ( column.equals("RCRD_CRTS") || column.equals("CREAT_USRID_RCRD") || column.equals("DEL_FLAG")) { } else { columnNamesAndParameters += column + "=?,"; } } columnNamesAndParameters = columnNamesAndParameters.substring( 0, columnNamesAndParameters.length() - 1); sql = sql.substring(0, sql.length() - 1) + " WHERE "; for (Iterator iter = table.getPrimaryKeys().iterator(); iter.hasNext(); ) { String column = (String) iter.next(); sql += column + "=? AND "; } sql = sql.substring(0, sql.length() - 5); out.println(sql); } out.close(); System.out.println("処理終了"); } /** * DB情報を取得してリストに格納して返す。 * @param driverName ドライバー名 * @param url URL * @param user DBユーザ名 * @param password DBパスワード * @param schem DBスキーマ名 * @return DB情報 * @throws ClassNotFoundException ドライバークラスが見つからない * @throws SQLException DBエラー */ public static ArrayList loadDBInfo( String driverName, String url, String user, String password, String schem) throws ClassNotFoundException, SQLException { Class.forName(driverName); Connection con = DriverManager.getConnection(url, user, password); DatabaseMetaData dbmd = con.getMetaData(); ResultSet rs = dbmd.getColumns(null, schem, "%", "%"); HashMap map = new HashMap(); while (rs.next()) { //printResultSet(rs); String tableName = rs.getString("TABLE_NAME"); String columnName = rs.getString("COLUMN_NAME"); String typeName = rs.getString("TYPE_NAME"); TableVO table = (TableVO) map.get(tableName); if (table == null) { table = new TableVO(); table.setName(tableName); loadPrimaryKeyList( dbmd, table.getName(), table.getPrimaryKeys(), schem); map.put(tableName, table); } table.getColumns().add(columnName); } rs.close(); con.close(); ArrayList list = new ArrayList(); Collection c = map.values(); for (Iterator iter = c.iterator(); iter.hasNext();) { TableVO e = (TableVO) iter.next(); list.add(e); } Collections.sort(list); return list; } /** * dbmdからschemスキーマのtableNameテーブルの主キー情報を取得して * listに格納して返す。 * @param dbmd DB定義情報 * @param tableName テーブル名 * @param list 主キー情報を格納するリスト * @param schem スキーマ名 * @throws SQLException DB例外 */ private static void loadPrimaryKeyList( DatabaseMetaData dbmd, String tableName, ArrayList list, String schem) throws SQLException { //ユニークインデックスで主キーを定義している場合は↓のコードを実行 ResultSet rs = dbmd.getIndexInfo(null, schem, tableName, true, true); //プライマリーキーで主キーを定義している場合は↓のコードのコメントを外す //ResultSet rs = dbmd.getPrimaryKeys(null, schem, tableName); while (rs.next()) { String s = rs.getString("COLUMN_NAME"); if (s != null) { list.add(s); } } rs.close(); } /** * ResultSetを標準出力する * @param rs 標準出力するResultSet * @throws SQLException DBエラー */ private static void printResultSet(ResultSet rs) throws SQLException { while (rs.next()) { ResultSetMetaData rm = rs.getMetaData(); for (int i = 1; i <= rm.getColumnCount(); i++) { System.out.println( i + ":" + rm.getColumnName(i) + ":" + rs.getString(i)); } } } } package tool.db; import java.util.ArrayList; import org.apache.commons.lang.builder.ToStringBuilder; /** * Table情報を格納する * @author yamarou */ public class TableVO implements Comparable { /** テーブル名 */ private String name; /** 列名リスト */ private ArrayList columns = new ArrayList(); /** 主キー名リスト */ private ArrayList primaryKeys = new ArrayList(); /** * オブジェクトの文字列表現を返します。 */ public String toString() { return ToStringBuilder.reflectionToString(this); } /** * 列名リストを返す * @return 列名リスト */ public ArrayList getColumns() { return columns; } /** * テーブル名を返す * @return テーブル名 */ public String getName() { return name; } /** * 主キー名リストを返す * @return 主キー列名リスト */ public ArrayList getPrimaryKeys() { return primaryKeys; } /** * テーブル名を設定する * @param string テーブル名 */ public void setName(String string) { name = string; } /** * オブジェクトを比較する。 */ public int compareTo(Object o) { TableVO table = (TableVO) o; return this.name.compareTo(table.getName()); } }/* ■実行 java tool.db.SQLGeneretor ■実行結果 c:/TEMP/sql.txtにテキストファイルが出来上がります。 [sql.txt] SELECT ~ INSERT ~ DELETE ~ UPDATE ~ ・ ・ ・ 続く この仕組みを使えばORマッピングクラスや、 JUnitのテストコード等、DB関連のコードを 自動生成したりといったことが出来ると思います。 なかなか使えそうですね♪ ■発行者メールアドレス(ご意見、ご感想、ご要望、ご質問等) yamarou@mail.goo.ne.jp ■発行者webサイト(バックナンバー一気に読めます、リンクで跳べます) http://yamarou.at.infoseek.co.jp/ ■バックナンバー・登録・解除・メールアドレスの変更 http://www.mag2.com/m/0000103290.htm
2009년 9월 29일 화요일
java.sql.DatabaseMetaDataを使うとDBのメタ情報
2009년 9월 24일 목요일
EL식 언어 활용
Javaの開発者にとって、式言語として最も身近なのは、JSPのELでしょう。
${aaa}
みたいにして、JSPの中に埋め込んでいる式のことです。上記の場合、aaaは変数になります。このELをプログラムの中から自由に呼び出せるといろんなことができるようになりますよね。
commons-elを使うとELを簡単に呼び出せるようになります。
キーとなるクラスは、ELParser。ELParser#ExpressionString(String expression)を呼び出すことにより、文字列をコンパイルします。
コンパイルした結果は、${}で囲まれている場合Expression型、そうでないばあいにはStringがそのまま返されます。
Expressionで重要なのは、Expression#evaluate(VariableResolver, FunctionMapper, Logger)のメソッド。VariableResolverを使って、式の中の変数を解決します。JSPのファンクションを解決するのが、FunctionMapperです。JSPのファンクションといっても実態は、public staticな任意のメソッドを呼び出すことができます。
http://svn.slim3.org/browse/trunk/slim3/slim3-commons/src/main/java/org/slim3/commons/el/にSlim3のEL実装があります。Mavenをお使いの方は、slim3-commonsのpom.xmlが参考になるでしょう。
それでは、S3VariableResolverを使ってみましょう。S3VariableResolverのコンストラクタの引数は、変数名と値を関連付けるMapです。
ELParser parser = new ELParser(new StringReader("${aaa}")); Object exp = parser.ExpressionString(); Map<String, Object> map = new HashMap<String, Object>(); map.put("aaa", "111"); System.out.println(((Expression) exp).evaluate(new S3VariableResolver(map), null, null);
の結果は、111と表示されます。
FunctionMapperの使い方はこんな感じ。
public static int add(int arg1, int arg2) { return arg1 + arg2; } public void testEvaluateFunction() throws Exception { S3FunctionMapper functionMapper = new S3FunctionMapper(); Method function = getClass().getDeclaredMethod("add", int.class, int.class); functionMapper.addFunction("f", "add", function); ELParser parser = new ELParser(new StringReader("${f:add(1,2)}")); Expression exp = (Expression) parser.EvaluateString(); assertEquals(3, exp.evaluate(null, functionMapper, null)); }
S3FunctionMapper#addFunction()の最初の引数はprefix、二番目の引数はlocalNameです。ここで登録したメソッドを${prefix:localName(...)}のような感じで呼び出します。
ねっ、簡単でしょ。
2009년 9월 20일 일요일
ZK
ZK http://www.zkoss.org/product/zk.dsp
ZK is the most proven Ajax + Mobile framework available, designed to maximize an enterprise’s operational efficiency and minimize development time and cost
With groundbreaking Direct RIA architecture, ZK simplifies and hastens the creation, deployment and maintenance of rich Internet applications
With direct UI implementation, developing web applications is as
straightforward and intuitive as programming desktop applications. By
directly communicating with database and enterprise resources,
developers have no need to worry about exposure of client side business
logic and business data in transit
The benefits of using ZK to enrich enterprise web applications are numerous:
Rich user experience: Leverage off-the-shelf Ajax components and versatile RIA features to create a responsive and engaging user experience maximizing user satisfaction and work efficiency
- Over 200 off-the-shelf state-of-art XUL/HTML-complaint Ajax components
- Numerous third party widgets: JFreeChart, JasperReports, Google Maps, FCKeditor, Timeline, Timeplot, ExtJS, Dojo etc.
- CSS-based skinning, template-based looks and customizable behavior
- Drag-and-drop, animation, context menus, and so on
- Bookmark management and SEO (Search Engine Optimization) supported
Direct RIA: ZK boosts developer’s productivity by allowing direct implementation and manipulation of user interfaces, databases and enterprise resources.
- With direct programming, developing Web applications is as straightforward and intuitive as programming desktop applications
- Displaying data client side is accomplished automatically by transparent and on-demand synchronization between client and server
Open Source: ZK is the leading open source Ajax + Mobile framework. The ZK developer community is extremely active with over 20 translations, 100 articles/blogs, 100,000 lines of codes, 1,000,000 downloads from 190+ countries.
Standards-based: ZK is a standard-compliant solution.
- With XUL and HTML compliant components, ZK protects enterprise applications from behind-closed-doors and proprietary technologies
- ZK also complies with JSP, JSF, Portlet and Java EE technologies, including the ability to integrate with existing enterprise environments and Java IDEs
Please click here for a complete list of supported platforms.
Markup and scripting Languages: ZK applications can be built using pure Java, markup and/or scripting languages.
- With XUL/XHTML, designing rich UIs is as simple as authoring HTML pages
- With Java, Groovy and various other scripting languages supported, developing applications is as rapid as prototyping
- With annotations and data-binding, accessing database and backend resources can be accomplished effortlessly without writing Java code
- With Web Accessibility compliance, enterprise applications can be easily be made accessible to people with disabilities
Direct Push: ZK provides exceptionally robust and intuitive Direct Push technology enabling spontaneous updates sent by the server to Ajax browsers and mobile devices. With ZK’s Direct Push technology, responsive and dynamic enterprise solutions can be created at minimal cost. The technology is also based on strict standards and therefore supports all kinds of application servers and browsers.
Extensibility and Customizability: ZK is fully customizable and extensible with a modular plug-and-play architecture.
- With CSS, templates and macro components, the look and behavior of components can be changed dramatically without modifying the application
- With a pluggable UI factory, each user can have a custom UI loaded from a database or other resource
- With pluggable variable resolvers and data binding, access to enterprise resources can be achieved automatically
- With a pluggable performance monitor, the performance of a ZK application can be measured easily; not only the processing time but the communication time aswell
Security: ZK is designed from the ground up to be secure. ZK protects enterprise applications from cross-site scripting, malicious JavaScript/SQL injection, exposure of client-side business logic, and exposure of business data in transit.
Scalability, Clustering and Failover: ZK supports high scalability and availability with serializable user interfaces and a pluggable failover manager. ZK is also compatible with the clustering and load balancing support found in modern application servers.
Mobile Access: ZK extends the reach of enterprise Internet applications to 1 billion mobile devices with minimal cost. ZK supports Java Mobile, Android, and various mobile browsers.
Enterprise Support: ZK technical support is designed to save development time and enable enterprises to achieve the highest level of user experience, productivity, and performance. Some of our supported customers include Sun Microsystems, Swiss Re, Unisys and MMC, just to name a select few.
ZK spreadsheet
http://www.zkoss.org/product/zkspreadsheet.dsp
ZK Spreadsheet
~ The 1st embeddable Ajax spreadsheet for Java Web application!
ZK Spreadsheet enables Ajax applications to deliver the rich functionality of Excel® within browsers using pure Java. With embeddable Excel® functionality, developers are able to create collaborative and dynamic enterprise applications at minimal cost.
Collaboration
- Data/Workspace sharing
- Permission controls
- Business Intelligence
- Import and Export Excel files
Ajax
- Internet access
- Excel look and feel
- Zero installation, no ActiveX controls needed, Excel doesn't need to be installed locally
- Compatible with IE6, IE7, Firefox, Safari, Opera,…
Component
- Embed ZK Spreadsheet in enterprise applications using pure Java
- Seamless integration with databases, Web services and other enterprise resources
- Collaboration with versatile components
Super Grid
- Large scale data sets
- Live Data
- Sorting, filtering, formulating and what-if analysis
- Excel reporting functionality
Excel Functionalities
- Over 225 Excel formula functions
- Fabulous styling
- Embed images and widgets
- Selecting, highlighting and merging-cells
- Freeze rows and columns, lock cells
[Java] include 집중해부
Last Modified 2003/06/06 Written by hsboy ReadCount 5287 |
JSP 에서는 두가지 방법으로 다른 문서를 현재의 문서에 포함 시킬수 있습니다.
이번 강좌에서는 이러한 두가지 include 문에 대해서 알아 봅니다.
* include 란?
다른 웹 언어(PHP or ASP등)를 프로그래밍 해본 경험이 있으신 분들은 include 가 무었인지 잘 알고 있을 것입니다.
그리고 doc2.jsp 의 내용이 아래와 같을때
위의 두개 문서의 출력을 한번에 보고자 할 때 include를 사용합니다.
위의 doc3.jsp 를 출력하면 아래와 같은 화면이 출력됩니다. doc3.jsp 실행화면 위의 소스에서 눈여겨 볼 부분이 doc2.jsp 의 상단 부분인데, doc2.jsp에는 page Directive가 생략 되어 있습니다. 이것은 두가지 include 방식의 차이 때문인데, 자세한 설명은 아래에서 하도록 하겠습니다. 또한 이러한 기능을 SSI(Server Side Include)를 이용해서 구현할수도 있는데 이것은 apache웹서버에서 지원하는 내용 이므로 여기에서는 다루지 않도록 하겠습니다. 자세한 내용이 궁금하신분은 여기를 참고 하시기 바랍니다.
위와 같이 두가지 사용 용법이 있으며, 두번째 방법을 사용하면 해당 jsp파일에 파라메터값도 넘겨 줄수가 있습니다.
include 지시어 와 Action 구문과의 가장 큰 차이점은 include 지시어는 컴파일 되기전에 파일이 내용이 합쳐진다는 것입니다. 즉, doc3.jsp 는 doc2.jsp의 내용을 자신의 문서내에 포함하여 하나의 파일로 인식한다는 것입니다. doc2.jsp 에 보면 page Directive 가 생략이 되어 있는데, 그것이 바로 이러한 이유 때문입니다. doc2.jsp에도 page Directive를 설정해 주었다면 에러가 발생할 것입니다. 하나의 페이지에 두번 선언을 하는 꼴이 되어 버릴테니까 말이죠.
JSP프로그래밍을 조금이라도 접해 보신 분들이라면 누구나 아는 대로 JSP는 먼저 servlet 으로 변환되고, 그 다음 servlet 이 컴파일 되어 그결과를 화면에 출력해 주게 되어 있습니다.
하지만 include 지시어 문을 사용하게 되면 하나의 servlet 파일이 생성되게 됩니다. 이로 인해 엄청난 차이점이 발생하게 되는데, JSP의 특성상 JSP파일이 조금이라도 수정이 되어 있으면 servlet 으로 재 변경되어 다시 컴파일이 이루어 지게 됩니다. 그런데, doc2.jsp 파일을 내용을 수정하고, doc3.jsp 파일을 부르게 되면 수정되기 전의 doc2.jsp 파일의 내용이 출력됩니다.
또다시 doc3.jsp 파일을 살짝 고치고 doc3.jsp 을 부르게 되면 이제서야 수정된 doc2.jsp파일의 내용이 화면에 출력 되게 될 것입니다. 눈치 빠르신 분들은 알아 차리셨으리라 생각됩니다만..
따라서, include 지시어 문을 사용하셨을 경우에는 두개의 파일 모두 수정해 주어야(doc3.jsp는 공백하나가 추가 되더라도 수정되어야 합니다) 원하는 결과를 얻을수가 있게 됩니다. |
2009년 9월 15일 화요일
HiRDB meta info read
2009년 9월 14일 월요일
[freemarker] readme.ftl テンプレートを使って [Template]
readme.ftl テンプレートを使って [Template]
Alfrescoには、スペースにreadme.htmlをいれておくと、
その内容をカスタム表示してくれるテンプレートが用意されています。
(1)readme.ftlの内容
<#-- Displays the contents of readme.html and/or the evaluated readme.ftl
if they exist in the current space. -->
<#assign htmlFilename = "readme.html"/>
<#assign ftlFilename = "readme.ftl"/>
<#if space?exists>
<#if space.childByNamePath["${htmlFilename}"]?exists>
${space.childByNamePath[htmlFilename].content}
</#if>
<#if space.childByNamePath["${ftlFilename}"]?exists>
<#include space.childByNamePath["${ftlFilename}"].nodeRef>
</#if>
</#if>
(2)readme.html
<html>
<head>
<title>readme</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<h4>**User&Group**</h4>
<table border="1">
<tr>
<td>No.</td>
<td>機能</td>
<td>呼出html</td>
<td>Javascript</td>
<td>データファイル名</td>
<td>log 又は list ファイル名</td>
</tr>
<tr>
<td>1</td>
<td>ユーザー作成</td>
<td>create_user.html</td>
<td>create_user.js</td>
<td>user_data.csv</td>
<td>create_user_log.txt</td>
</tr>
<tr>
<td>2</td>
<td>グループ作成</td>
<td>create_group.html</td>
<td>create_group.js</td>
<td>group_UTF-8.csv</td>
<td>create_group_log.txt</td>
</tr>
<tr>
<td>3</td>
<td>ユーザーをグループに登録</td>
<td>addperson.html</td>
<td>addperson.js</td>
<td>user_data.csv</td>
<td>addperson_log.txt</td>
</tr>
<tr>
<td>4</td>
<td>フォルダにグループとパーミッションをセット</td>
<td>permission_set.html</td>
<td>permission_set.js</td>
<td>permission_data.csv</td>
<td>permission_set_log.txt</td>
</tr>
<tr>
<td>5</td>
<td>フォルダのリストを取る</td>
<td>folder_list.html</td>
<td>folder_list.js</td>
<td> </td>
<td>folder_list.txt</td>
</tr>
<tr>
<td>6</td>
<td>グループと属するメンバーのリストを作成</td>
<td>group_list.html</td>
<td>group_list.js</td>
<td> </td>
<td>group_member_list.txt</td>
</tr>
</table>
<br>*注意*<br>
1.データファイルはdataFolderに、
scriptはprogramFolderにある。結果はloglistFolderにできる<br>
2.実際に使用するときは、
現在テスト用にしてあるフォルダ名などを変更する必要有り<br>
</body>
</html>
(3)スペースにreadme.htmlをアップロードして、カスタム表示に
readme.ftlテンプレートを適用すると、
となります。
(注)画面に表示されているJavascriptなどはテスト用に実際に作成したものです。
呼び出しhtmlはアンカーをつければ、この画面から開くこともできます。
コンテナ数・ドキュメント数を表示するテンプレート [Template]
スペースのコンテナ数(サブフォルダ数)とドキュメント数を表示する
テンプレートを作成しました。
(あるスペースの下の階層の全サブフォルダ・全ドキュメントの名前と数を調べる
必要に迫られてJavascriptを作った時に使用したものの一部です)
(1)count02.ftl を作成
Company Home>Data Dictionary> Presentation Templates スペースにアップロード
<b>${space.name} children count: ${space.children?size}</b><br>
<#assign countC = 0>
<#assign countD = 0>
<#assign countR = 0>
<#list space.children as child>
<#if child.isContainer>
<#assign countC = countC + 1>
<#elseif child.isDocument>
<#assign countD = countD + 1>
<#else>
<#assign countR = countR + 1>
<#assign othername = child.name>
</#if>
</#list>
${space.name} children Container count: ${countC}<br>
${space.name} children Document count: ${countD}<br>
${space.name} children ruleFolder count: ${countR}<br>
(2)MyHomeのカスタム表示に、そのテンプレートを適用する
(注)このテンプレートでは、スペース直下のフォルダ数ドキュメント数しか表示されません。
バージョン履歴 [Template]
Alfrescoではコンテンツのバージョン管理ができる
(バージョンのつけ方の説明は後日にゆずる
前回テンプレートのことを書いたので、バージョンの履歴をテンプレートで表示してみる)
(1) version を表示するテンプレートをつくり
Company Home > Data Dictionary > Presentation Templates スペースにアップロードする
http://wiki.alfresco.com/wiki/FreeMarker_Template_Cookbook を参考にしてテンプレート作成
(2) webclient から見ると
**** とても便利な機能です。
メールのテンプレートを日本語化 [Template]
2009/05/20 メールのテンプレートを日本語化
(1)Alfrescoではwebclientのアクション・JavaScript・workflowなどいろいろな場面から
メールを出すことができる。
Company Home > Data Dictionary > Email Templates スペースに
そのためのメールテンプレートが用意されている。
今回はそれを日本語化したものを作ってみた。
それを上記スペースにアップロードしておけば、利用時に選択できる。
(2) invite_user_email.ftl ----> invite_user_emai_ja.ftl
**テンプレートの内容**
あなたは、スペース '${space.name}' に招待されました。
招待したのは '${person.properties.firstName}<#if person.properties.lastName?exists>
${person.properties.lastName}</#if>'.
権限は the role of: ${role} です。
スペースへのリンク:
<#assign ref=space.nodeRef>
<#assign workspace=ref[0..ref?index_of("://")-1]>
<#assign storenode=ref[ref?index_of("://")+3..]>
http://yourserver:8080/alfresco/navigate/browse/${workspace}/${storenode}
お知らせでした。
Alfresco
(3) notify_user_email.ftl -----> notify_user_email_ja.ftl
**テンプレートの内容**
新しい投稿 '${document.name}'が、スペース'${space.name}' に届きました。
届けたのは '${person.properties.firstName}<#if person.properties.lastName?exists>
${person.properties.lastName}</#if>'.
ドキュメントへのリンク:
http://yourserver:8080/alfresco${document.url}
スペースへのリンク:
<#assign ref=space.nodeRef>
<#assign workspace=ref[0..ref?index_of("://")-1]>
<#assign storenode=ref[ref?index_of("://")+3..]>
http://yourserver:8080/alfresco/navigate/browse/${workspace}/${storenode}
お知らせでした。
Alfresco
(3) 利用例
(4) Alfresco では テンプレートとして freemarker がよく使用される
参考URL http://freemarker.org/
マニュアルのURL http://freemarker.org/docs/index.html
(注意) ftl ファイルはテキストファイルだが、UTF-8で保存するこ
2009년 9월 12일 토요일
Java-FreeMarkerのサンプル
Java-FreeMarkerのサンプル |
FreeMarkerの一番最初のサンプルです。
netbeans6.1でテストしてみましたが、test.ftlはutf-8で保存されるのですが、
それだと実行したときにtest.ftlに書いた日本語(朝、昼、夜)が文字化けします。
別のエディタで、shift_jisに変更して保存するとすべて正常に表示されます。
配列を使用した例
test.ftl
<html>
<head>
<title>FreeMarker Example Web Application 1</title>
<meta http-equiv="Content-type" content="text/html; charset=shift_JIS">
</head>
<body>
${message}
<br><br>
<table>
<tr><td>朝</td><td>昼</td><td>夜</td></tr>
<#list ar as val>
<tr>
<#list val as v>
<td>${v}</td>
</#list><br>
</tr>
</#list>
</body>
</html>
HelloServlet.java
package example;
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import freemarker.template.*;
import java.lang.reflect.Array;
public class HelloServlet extends HttpServlet {
private Configuration cfg;
public void init() {
cfg = new Configuration();
cfg.setServletContextForTemplateLoading(
getServletContext(), "WEB-INF/classes/templates");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Build the data-model
Map root = new HashMap();
root.put("message", "おはようございます");
String[] ar = {"おはようございます","こんにちは","こんばんは"};
String[] br = {"goog morning","good arternoon","Goodevening"};
ArrayList cr = new ArrayList();
cr.add(ar);
cr.add(br);
root.put("ar", cr);
Template t = cfg.getTemplate("test.ftl");
resp.setContentType("text/html; charset=" + t.getEncoding());
Writer out = resp.getWriter();
try {
t.process(root, out);
} catch (TemplateException e) {
throw new ServletException(
"Error while processing FreeMarker template", e);
}
}
}
MAPを使用した例
test2.ftl
<html>
<head>
<title>FreeMarker Example Web Application 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=MS932">
</head>
<body>
${message}
<hr>
<table border=1>
<tr><th>朝</th><th>昼</th><th>夜</th>
<#list ar as value>
<tr><td>${value.a}<td>${value.b}<td>${value.c!"<br>"}</tr>
</#list>
</table>
<br><br>
これはテストの表示です
</body>
</html>
HelloServlet2.java
package example;
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import freemarker.template.*;
public class HelloServlet2 extends HttpServlet {
private Configuration cfg;
public void init() {
cfg = new Configuration();
cfg.setServletContextForTemplateLoading(
getServletContext(), "WEB-INF/classes/templates");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Map root = new HashMap();
root.put("message", "Hello World!");
HashMap ar = new HashMap();
HashMap br = new HashMap();
ar.put("a", "おはようございます");
ar.put("b", "こんにちは");
ar.put("c", "こんばんは");
br.put("a", "Good Morning");
br.put("b", "Good Afternoon");
Object[] cr = {ar, br};
root.put("ar", cr);
Template t = cfg.getTemplate("test2.ftl");
resp.setContentType("text/html; charset=" + t.getEncoding());
Writer out = resp.getWriter();
try {
t.process(root, out);
} catch (TemplateException e) {
throw new ServletException(
"Error while processing FreeMarker template", e);
}
}
}
SAP(ABAP) 관련 좋은 사이트
SAP(ABAP) 관련 좋은 사이트
Sap
2008/11/07 01:33 http://blog.naver.com/tyboss/70036990289 |
<이 자료는 2006 Vision님의 블로그에서 퍼 온 글입니다. >
http://cma.zdnet.com/book/abap/ch03/ch03.htm
http://help.sap.com/saphelp_40b/helpdata/en/4f/991f82446d11d189700000e8322d00/applet.htm SAP Online Help For Dictionary.
http://sappoint.com/abap/ for SAPscripts
For follg., refer http://www.henrikfrank.dk/abapuk.html
Please note that I do not offer any support for the examples !
ABAP objects and control technology
IDOC
SapScript
Performance tuning
BAPI Programming
Visual Basic Integration - Using the DCOM Connector and BAPI OCX (Only available in Danish)
JAVA and the SAP java connector
http://www.sts.tu-harburg.de/teaching/sap_r3/ABAP4/abapindx.htm
for keywords
very useful link for all
http://www.sapgenie.com/abap/index.htm
http://www.sap-img.com/abap.htm
http://www.sapdevelopment.co.uk/tips/tipshome.htm
http://help.sap.com/printdocu/core/Print46c/en/Data/Index_en.htm
http://sap.ittoolbox.com/nav/t.asp?t=322&p=322&h1=322
http://sap.ittoolbox.com/nav/t.asp?t=448&p=448&h1=448
http://www.thespot4sap.com/
http://www.kabai.com/abaps/q.htm
http://www.geocities.com/mpioud/Abap_programs.html
http://www.sapgenie.com/abap/tips_and_tricks.htm
http://www.sapassist.com/code/d.asp?whichpage=1&pagesize=10&i=10&a=c&o=&t=&q=&qt=
For FAQ
http://www.sap-img.com/abap/more-than-100-abap-interview-faqs.htm
http://www.sapgenie.com/faq/abap.htm
BAPI-step by step
http://www.sapgenie.com/abap/bapi/example.htm
http://www.sapgenie.com/abap/bapi/example.htm
Weblog for receive email and processing it through ABAP
https://www.sdn.sap.com/sdn/weblogs.sdn?blog=/pub/wlg/795
For Logical database
http://help.sap.com/saphelp_46c/helpdata/en/9f/db9bed35c111d1829f0000e829fbfe/frameset.htm
very useful
http://help.sap.com/saphelp_46c/helpdata/EN/35/2cd77bd7705394e10000009b387c12/frameset.htm
Useful link to websites
http://www.hernangn.com.ar/sap.htm
Useful for background
http://www.sappoint.com/basis/bckprsng.pdf
http://help.sap.com/saphelp_nw04/helpdata/en/6f/08703713bf277ee10000009b38f8cf/frameset.htm
http://publib.boulder.ibm.com/infocenter/wbihelp/index.jsp?topic=/com.ibm.wbix_adapters.doc/doc/mysap4/sap4x41.htm
Table control in BDC
http://www.sap-img.com/abap/bdc-example-using-table-control-in-bdc.htm
For posting weblog,
https://www.sdn.sap.com/sdn/weblogs.sdn?blog=/pub/wlg/1936
Dynamic Internal table -weblog in sdn
https://www.sdn.sap.com/sdn/weblogs.sdn?blog=/pub/wlg/1011
Smartforms
http://www.sap-basis-abap.com/sapsf001.htm
http://www.sap-press.com/downloads/h955_preview.pdf
http://www.ossincorp.com/Black_Box/Black_Box_2.htm
http://www.sap-img.com/smartforms/sap-smart-forms.htm
http://www.sap-img.com/smartforms/smartform-tutorial.htm
http://www.sapgenie.com/abap/smartforms.htm
How to trace smartform
http://help.sap.com/saphelp_47x200/helpdata/en/49/c3d8a4a05b11d5b6ef006094192fe3/frameset.htm
For step-by-step explanations,check here.
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/uuid/ccab6730-0501-0010-ee84-de050a6cc287
https://sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/uuid/8fd773b3-0301-0010-eabe-82149bcc292e
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/uuid/3c5d9ae3-0501-0010-0090-bdfb2d458985
Workflow
http://www.sap-img.com/workflow/sap-workflow.htm
http://help.sap.com/saphelp_47x200/helpdata/en/a5/172437130e0d09e10000009b38f839/frameset.htm
For examples on WorkFlow...check the below link..
http://help.sap.com/saphelp_47x200/helpdata/en/3d/6a9b3c874da309e10000000a114027/frameset.htm
http://help.sap.com/printdocu/core/Print46c/en/data/pdf/PSWFL/PSWFL.pdf
http://help.sap.com/saphelp_47x200/helpdata/en/4a/dac507002f11d295340000e82dec10/frameset.htm
http://www.workflowing.com/id18.htm
http://www.e-workflow.org/
http://web.mit.edu/sapr3/dev/newdevstand.html
ALV
http://www.geocities.com/mpioud/Abap_programs.html
Conversion ALV to E-mail,PDF
http://www.sapdevelopment.co.uk/reporting/rep_spooltopdf.htm
Mail
http://www.geocities.com/mpioud/Z_EMAIL_ABAP_REPORT.html
http://www.thespot4sap.com/Articles/SAP_Mail_SO_Object_Send.asp
http://www.sapdevelopment.co.uk/reporting/email/attach_xls.htm
Rich Heilman has provided sample code for sending mail in html-format:
https://www.sdn.sap.com/irj/sdn/thread?forumID=50&threadID=64062&messageID=679478
Sending mail in background or spool mail
http://www.sap-basis-abap.com/sapac018.htm
BOM Explosion
https://www.sdn.sap.com/sdn/weblogs.sdn?blog=/pub/wlg/1647
BOM
http://help.sap.com/saphelp_erp2005/helpdata/en/ea/e9b7234c7211d189520000e829fbbd/frameset.htm
http://help.sap.com/saphelp_erp2005/helpdata/en/d1/2e4114a61711d2b423006094b9d648/frameset.htm
http://www.sap-img.com/sap-sd/sales-bom-implementation.htm
http://www.sap-basis-abap.com/sappp007.htm
OLE
http://www.sapgenie.com/abap/ole.htm
http://help.sap.com/saphelp_46c/helpdata/en/59/ae3f2e488f11d189490000e829fbbd/frameset.htm
ALVGRID with refresh
http://www.geocities.com/mpioud/Z_DEMO_ALV_REFRESH_BUTTON.html
For language setting and decimal separator
https://www.sdn.sap.com/sdn/weblogs.sdn?blog=/pub/wlg/1015
Oracle queries
http://sqlzoo.net/
To format SQL
http://www.sqlinform.com/
SCOT settings
http://www.sap-img.com/basis/basis-faq.htm
Status Icon [ALV,Table Control,Tab Strip]
http://www.sapdesignguild.org/resources/MiniSG-old/from_develop/norm_status_icons.htm#positioning_4
ALV Group Heading
http://www.sap-img.com/fu037.htm
For multiMedia
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/995
Uploading LOGO in SAP
http://www.sap-img.com/ts001.htm
LSMW
http://www.sap-img.com/sap-data-migration.htm
http://www.sapgenie.com/saptech/lsmw.htm
http://sapabap.iespana.es/sapabap/manuales/pdf/lsmw.pdf
http://www.sap.info/public/INT/int/glossary/int/glossaryletter/Word-17643ed1d6d658821_glossary/L#Word-17643ed1d6d658821_glossary
OOPS ALV
OOPS - Events.
Editable ALV
Tree
TabStrip
Multigrid
Check this for basic concepts of OOPS
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/webas/abap/abap%20code%20samples/ABAP%20Objects/ABAP%20Code%20Sample%20to%20Learn%20Basic%20Concept%20of%20Object-Oriented%20Programming.doc
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/webas/abap/abap%20code%20samples/ALV%20grid/ABAP%20Code%20Sample%20to%20Display%20Data%20in%20ALV%20Grid%20Using%20Object%20Oriented%20Programming.doc
Tree
http://www.sapdevelopment.co.uk/reporting/alv/alvtree/alvtree_usrint.htm
General Tutorial for OOPS
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/webas/abap/An%20Easy%20Reference%20for%20ALV%20Grid%20Control.pdf
Function Module
http://www.geocities.com/victorav15/sapr3/abapfun.html
Smartforms
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/uuid/ccab6730-0501-0010-ee84-de050a6cc287
https://sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/uuid/8fd773b3-0301-0010-eabe-82149bcc292e
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/uuid/3c5d9ae3-0501-0010-0090-bdfb2d458985
[출처] SAP(ABAP) 관련 좋은 사이트|작성자 마루아라
Freemarker사용법 [출처] Freemarker사용법|작성자 sikunix
1. @macro
- 프리마커 템플릿 전역에서 공통으로 사용되는 UI 디펜던트한 함수는 매크로로 만들어 여러 ftl에서 사용할 수 있도록 해준다. 샘플을 참고하도록 한다.
- 형식 : <@매크로명 변수1, 변수2, ... />
- 샘플1) 긴 문자열을 적당한 크기로 자르는 기능의 매크로
*사용법 : <@trimX ${item.title}, 20 />
*매크로 :
<#macro trimX src max><#compress>
<#if src?length > max>
${src[0..max-1]}..
<#else>
${src}
</#if>
</#compress></#macro>
- 샘플2) YYYYMMDD 형식의 문자열을 YYYY.MM.DD 형식으로 변환하는 매크로
*사용법 : <@parseDay ${item.regdate} />
*매크로 :
<#macro parseDay src><#compress>
<#if src?length == 8>
${src[0..3]}.${src[4..5]?number}.${src[6..7]?number}
<#else>
${src}
</#if>
</#compress></#macro>
2. #list
- 배열 형식의 오브젝트를 루핑 처리할때 사용하는 프리마커 지시자이다. “로컬엘리어스_index” 라는 변수는 0부터 시작하는 시퀀스번호이다.
- 형식 : <#list 배열객체 as 로컬엘리어스명></#list>
- 샘플1)
<#list LIST as item>
번호 : ${item_index+1} | 이름 : ${item.name} | 아이디 : ${item.id}
</#list>
3. #if
- 프리마커 조건문에 사용되는 지시자이다.
- 형식 : <#if 조건식></#if>
- 샘플1) string 비교
<#if ENTITY.usergrade == “A” >......</#if>
- 샘플2) number 비교
<#if ENTITY.userclass?number == 3>.....</#if>
- 샘플3) boolean 비교
<#if ENTITY.isAuth()>.....</#if>
4. #break
- Loop문을 중단하고 다음 스크립트로 넘어가려고 할때 사용되는 지시자이다.
- 형식 : <#break>
- 샘플1) 루프문을 실행하는 중 5번째에서 escape 하는 예
<#list LIST as item>
<#if item_index > 3><#break></#if>
</#list>
5. #assign
- 프리마커내에서 사용자 정의 로컬변수가 필요할 때 사용하는 지시자이다.
- 형식 : <#assign 로컬변수명 = 초기화값>
- 샘플1) <#assign CHECK = item_index>
6. [x...y]
- 문자열의 일정 범위를 자를때 사용하는 함수
- 형식 : ${문자열[1..5]}
- 샘플1) ${item.name[1..5]}
7. ?has_content
- 리스트형 오브젝트가 null이 아니고 최소 1개 이상의 컨텐츠를 가지고 있는지 체크하는 함수로써 ?has_content는 ?exists와 ?size>0 두가지 체크를 동시에 해주는 함수이다.
- 형식 : 리스트오브젝트?has_content
- 샘플1) <#if LIST?has_content>.....</#if>
8. ?exists
- NULL체크 함수. if_exists는 <#if 지시자 없이도 사용할 수 있게 해주는 표현식이다.
- 형식 : 오브젝트?exists
- 샘플1) <#if ENTITY.username?exists>${ENTITY.username?substring(0, 5)}</#if>
- 샘플2) <#if LIST?exists && LIST?size > 0>.....</#if>
- 샘플3) ${ENTITY.username?if_exists}
9. ?default
- NULL값을 대체해주는 함수
- 형식 : 오브젝트?default(디폴트값)
- 샘플1) ${item.userclass?default(“99”)}
- 샘플2) ${item.age?default(20)}
10. ?string
- 문자열로 형변환하는 함수
- 형식 : 오브젝트?string
- 샘플1) <#if item.age?string == “29”>.....</#if>
- 샘플2) ${item.regdate?string(“yyyy/MM/dd HH:mm”)}
- 샘플3) 숫자를 통화표시로 나타내는 예
<#assign MONEY = 1234567>
${MONEY?string(",##0")}
11. ?number
- 숫자로 형변환하는 함수
- 형식 : 오브젝트?number
- 샘플1) <#if item.userclass?number > 3>.....</#if>
- 샘플2) ${LIST_POINTS[item.gid?number].entityname?default(“”)}
12. ?js_string
- 문자열을 자바스크립트에 유효하도록 필터링해주는 함수. 문자열내에 싱글쿼테이션(‘)등이 포함되어 스크립트에 오류가 나는것을 방지하기 위하여 사용되는 함수이다. 화면상에는 HTML 태그로 취급된다.
- 형식 : 오브젝트?js_string
-
샘플1) 문자열 <img src=’/image/enterprise.gif’>을 js_string으로 처리했을때
소스보기를 하면 <img src=\’/image/enterprise.gif\’>으로 출력된다.
- 샘플2) <a href=”javascript
13. ?html
- 문자열을 HTML Symbolic Entity로 필터링해주는 함수. 문자열내의 HTML태그등을 깨뜨려 화면상으로 출력되도록 할때 사용하는 함수이다. 화면상에 HTML태그가 아닌 일반 문자열로 취급된다.
- 형식 : 오브젝트?html
-
샘플1) 문자열 <img src=’/image/enterprise.gif’>을 html로 처리하면 화면상에
<img src=’/image/enterprise.gif’> 로 출력되고 소스보기를 하면 <img
src=’/image/enterprise.gif’>로 출력된다.
14. ?index_of
- 특정 문자(열)가 시작되는 위치를 정수형으로 반환한다. 인덱스는 0부터 시작됨.
- 형식 : 오브젝트?index_of(특정문자)
- 샘플1) “abcde”?index_of(“c”) 는 2를 반환한다.
15. ?replace
- 문자열의 일부를 주어진 문자로 대체하는 함수
- 형식 : 오브젝트?replace(찾을문자열, 대체할문자열)
- 샘플1) ${item.content?replace(“>”, “>”)}
16. item_has_next
-리스트 객체의 다음 컨텐츠가 존재하는지(EOF) 체크하는 함수
-형식 : 리스트엘리어스이름_has_next
-샘플1) 이름과 이름사이에 , 를 찍어주되 마지막은 찍지 않는 경우의 예
<#list LIST as item>
${item.name?default(“”)}<#if item_has_next>,</#if>
</#list>
[출처] Freemarker사용법|작성자 sikunix
Freemarker에서 사소하지만 사실은 중요한 공백 처리 문제 [출처] Freemarker에서 사소하지만 사실은 중요한 공백 처리 문제|작성자 운용
Freemarker나 각족 템플릿 엔진들을 사용하다 보면, 우리는 직면하게 되는 문제가 하나 있습니다. 바로 공백이나 줄 바꿈 문제입니다. 각종 템플릿 관련 태그들을 쓰다보면 줄도 바꾸게 되고, 이게 어떻게 처리되는가에 따라서 공백이 민감한 파일들에 대해서는 오작동을 유도하기도 하고, 파일 용량 자체를 필요 이상으로 늘리기도 합니다.
그렇다면 Freemarker에서는 어떻게 공백을 합리적인 수준으로 제어할 수 있을까요? 이에 대해서 3가지 방법을 우선 생각할 수 있습니다.
- 방법 1. 줄 단위로 trim을 처리한다.
- 본 방법은 텍스트 줄 별로 <#t> <#lt> <#rt>을 걸어서 줄 전체에 trim을 걸거나 왼쪽, 오른쪽에 선택적으로 trim을 걸어준다.
- 방법 2. ftl 태그를 사용해서 freemarker 페이지에 strip_whitespace 세팅을 걸어준다.
- 템플릿 상단 부에 <#ftl strip_whitespace=true>를 걸어두고 신경을 끄도록 한다.
- 이 방법이 부하를 줄까 생각을 하지만, 해당 부분에 대해서는 그다지 신경을 많이 쓰지 않아도 된다고 한다.
- 방법 3. compress 메소를 사용해서 원하는 영역에서 공백을 제거해준다.
- 원하는 영역을 <#compresss>와 </#compress>로 묶어서 지정된 구간에 대해서 공백을 제거하도록 한다.
위 방법을 적절히 사용해서 공백 처리를 잘 하도록 하자.
경우에 따라서 공백이 문제를 일으키면 오작동 이유를 찾기 어려운 경우가 많다. 각별히 신경써서 조처하도록 하자.
[출처] Freemarker에서 사소하지만 사실은 중요한 공백 처리 문제|작성자 운용
Freemarker에서 상대 경로에서 context root 지정하기 [출처] Freemarker에서 상대 경로에서 context root 지정하기|작성자 sikunix
Freemarker를 다른 웹-어플리케이션 개발에 연동을 하면서 제일 먼저 직면하는 것 중에서 다른 리소스에 대한 링크를 만들고자 할 때 이른바 서비스 컨택스트 루트를 매번 써주어야 하는가 있다. 당연히 그렇지 않다. 그럼 어떻게 해야 하는가!
${base}를 사용하면 context root까지 경로가 기입된다.
예를 들어서, sample이라는 서비스 컨텍스트를 사용하는 경우에 각종 파일들은 /sample/***.** 형태로 나오게 된다. 그럴 때, 내부 자원에 대해서 링크를 걸어 줄 때는 /sample/을 명시적으로 써주어야 하는 경우들이 있다. 문제는 컨텍스트 이름이 바뀌는 경우이다. 서비스 만들다 보면 그런 경우 빈번하고. 그렇기에 우리는 삽질 하지 않을 방법을 찾아야 한다. 그래서 ${base}를 Freemarker가 제공해 주는 것이다.
간단한 팁이지만 알고 있어야 할 팁 중 하나 ${base} ^^
[FreeMarker] Built-ins for strings
- substring
FreeMarker 2.3.7 부터 지원
exp?substring(from, toExclusive) 또는 exp?substring(from) 의 형태로 사용
string의 substring. from 은 첫 문자의 인덱스입니다. from 은 0 이상이고, toExclusive 보다 작거나 같아야 합니다. toExclusive 는 부분 문자열의 다음 문자의 인덱스입니다. toExclusive 는 0 이상이고, 문자열 길이보다 작거나 같아야 합니다. toExclusive 를 생략하면 문자열의 길이로 설정됩니다. 정수가 아닌 숫자를 from 이나 toExclusive으로 사용하는 경우 정수 부분만 사용됩니다.
예
- ${'abc'?substring(0)}
- ${'abc'?substring(1)}
- ${'abc'?substring(2)}
- ${'abc'?substring(3)}
- ${'abc'?substring(0, 0)}
- ${'abc'?substring(0, 1)}
- ${'abc'?substring(0, 2)}
- ${'abc'?substring(0, 3)}
- ${'abc'?substring(0, 1)}
- ${'abc'?substring(1, 2)}
- ${'abc'?substring(2, 3)}
결과
- abc
- bc
- c
-
-
- a
- ab
- abc
- a
- b
- c
- cap_first
첫 번째 word 의 첫 문자가 대문자인 문자열. word 의 정확한 의미는 word_list built-in 에서 볼 수 있습니다.
예
${" green mouse"?cap_first}
${"GreEN mouse"?cap_first}
${"- green mouse"?cap_first}
결과
Green mouse
GreEN mouse
- green mouse
- upcap_first
cap_first 의 반대. 첫 word 의 첫 문자가 소문자인 문자열.
- capitalize
모든 word의 첫 문자가 대문자인 문자열. word 의 정확한 의미는 word_list built-in 에서 볼 수 있습니다.
예
${" green mouse"?capitalize}
${"GreEN mouse"?capitalize}
결과
Green Mouse
Green Mouse
- chop_linebreak
끝에 line_break 가 없는 문자열.
- date, time, datetime
date 값으로 변환된 문자열. 형식에 대한 파라미터를 명시하는 것을 추천합니다.
예
<#assign test1 = "10/25/1995"?date("MM/dd/yyyy")>
<#assign test2 = "15:05:30"?time("HH:mm:ss")>
<#assign test3 = "1995-10-25 03:05 PM"?datetime("yyyy-MM-dd hh:mm a")>
${test1}
${test2}
${test3}
결과
Oct 25, 1995
3:05:30 PM
Oct 25, 1995 3:05:00 PM
date 가 date_format, time_format, datetime_format 설정에 따라 변환되었다는 것을 유의하십시오. (date 를 string 으로 변환하는 것에 대한 자세한 정보는 string built-in for dates, date interpolations 에서 볼 수 있습니다.) string 을 date 로 변환할 때 사용한 형식은 중요하지 않습니다.
기본 date/time/datetime 형식이 무엇일지 알고 있다면 형식 파라미터를 사용할 필요가 없습니다.
<#assign test1 = "Oct 25, 1995"?date>
<#assign test2 = "3:05:30 PM"?time>
<#assign test3 = "Oct 25, 1995 03:05:00 PM"?datetime>
${test1}
${test2}
${test3}
- ends_with
- html
html 문자열. 즉, < 는 < 로, > 는 > 로, & 는 & 로, " 는 " 로 치환된 문자열.
안전하게 속성 값을 삽입하고자 한다면, HTML 에서 속성 값을 큰 따옴표로 둘러싸야 한다는 것에 유의하십시오.
<input type=text name=user value="${user?html}">
일반적으로 많은 타이핑을 없애고, escape directive 를 사용함으로써 발생할 수 있는 실수의 가능성을 줄이기 위해, HTML 에서 모든 것에 이 built-in 을 사용하고 싶을 것입니다.
- groups
matches built-in 의 결과에만 사용됩니다.
- index_of
특정 문자열이 처음 나타나는 인덱스를 반환합니다. 예를 들어, "abcabc"?index_of("bc") 는 1을 반환합니다. (첫 문자의 인덱스가 0 입을 잊지 마십시오.) 검색을 시작할 인덱스를 지정할 수도 있습니다. "abcabc"?index_of("bc", 2) 는 4를 반환합니다. 두 번째 파라미터의 숫자는 제한이 없습니다. 두 번째 파라미터가 0 보다 작으면, 두 번째 파라미터가 0일 때와 같은 결과를 반환합니다. 두 번째 파라미터가 문자열의 길이보다 크면, 두 번째 파라미터가 문자열의 길이일 때와 같은 결과를 반환합니다. 파라미터가 소수면, 내림한 정수를 사용하여 결과를 반환합니다.
문자열에 첫 번째 파라미터가 존재하지 않으면 -1 을 반환합니다.
- j_string
Java 언어의 문자열 escaping 규칙에 따라 문자열을 수정합니다. 게다가 Java 언어에 해당하는 escape sequence 가 없는 모든 문자(UCS code point 0x20) 는 UNICODE escape (\uXXXX) 으로 변경됩니다..
예
<#assign beanName = 'The "foo" bean.'>
String BEAN_NAME = "${beanName?j_string}";
결과
String BEAN_NAME = "The \"foo\" bean.";
- js_string
JavaScript 언어 문자열 escaping 규칙에 따라 문자열을 변경합니다. 큰 따옴표(") 와 작은 따옴표(') 가 모두 변경됩니다. FreeMarker 2.3.1 부터 > 는 \> 로 치환됩니다. 게다가 JavaScript 에 escape sequence 가 없는 모든 문자 (UCS code point 0x20) 은 16진수 escape (\xXX) 로 치환됩니다. (물론, JavaScript 언어 문자열 syntax 에 따라 백슬래쉬(\) 도 변경되고, line-feed 는 \n 으로 치환됩니다. 등)
예
<#assign user = "Big Joe's \"right hand\"">
<script>
alert("Welcome ${user?js_string}!");
</script>
결과
<script>
alert("Welcome Big Joe\'s \"right hand\"!");
</script>
- last_index_of
- length
문자열의 문자 개수
- lower_case
소문자로 이루어진 문자열
- left_pad
FreeMarker 2.3.1 부터 지원
파라미터가 1 개면, 문자열의 길이가 파라미터의 값과 같아질 때까지 문자열의 앞에 공백을 삽입합니다. 만약 문자열의 길이와 파라미터와 같거나 파라미터보다 크면 아무 작업도 하지 않습니다.
예
[${""?left_pad(5)}]
[${"a"?left_pad(5)}]
[${"ab"?left_pad(5)}]
[${"abc"?left_pad(5)}]
[${"abcd"?left_pad(5)}]
[${"abcde"?left_pad(5)}]
[${"abcdef"?left_pad(5)}]
[${"abcdefg"?left_pad(5)}]
[${"abcdefgh"?left_pad(5)}]
결과
[ ]
[ a]
[ ab]
[ abc]
[ abcd]
[abcde]
[abcdef]
[abcdefg]
[abcdefgh]
파라미터가 2 개일 때, 첫 번째 파라미터는 앞에서 언급한 파라미터와 같은 역할을 합니다. 두 번째 파라미터는 문자열의 앞에 삽입할 문자 입니다.
예
[${""?left_pad(5, "-")}]
[${"a"?left_pad(5, "-")}]
[${"ab"?left_pad(5, "-")}]
[${"abc"?left_pad(5, "-")}]
[${"abcd"?left_pad(5, "-")}]
[${"abcde"?left_pad(5, "-")}]
결과
[-----]
[----a]
[---ab]
[--abc]
[-abcd]
[abcde]
두 번째 파라미터는 문자열이 될 수도 있습니다. 그러면 문자열인 파라미터가 반복하여 삽입됩니다.
예
[${""?left_pad(8, ".oO")}]
[${"a"?left_pad(8, ".oO")}]
[${"ab"?left_pad(8, ".oO")}]
[${"abc"?left_pad(8, ".oO")}]
[${"abcd"?left_pad(8, ".oO")}]
결과
[.oO.oO.o]
[.oO.oO.a]
[.oO.oOab]
[.oO.oabc]
[.oO.abcd]
두 번째 파라미터는 반드시 길이가 1 이상인 문자열이어야 합니다.
- right_pad
FreeMarker 2.3.1 부터 지원됩니다.
이 것은 left_pad 와 같지만, 두 번째 파라미터(또는 공백)을 문자열의 앞이 아니라 뒤에 삽입합니다.
예
[${""?right_pad(5)}]
[${"a"?right_pad(5)}]
[${"ab"?right_pad(5)}]
[${"abc"?right_pad(5)}]
[${"abcd"?right_pad(5)}]
[${"abcde"?right_pad(5)}]
[${"abcdef"?right_pad(5)}]
[${"abcdefg"?right_pad(5)}]
[${"abcdefgh"?right_pad(5)}]
[${""?right_pad(8, ".oO")}]
[${"a"?right_pad(8, ".oO")}]
[${"ab"?right_pad(8, ".oO")}]
[${"abc"?right_pad(8, ".oO")}]
[${"abcd"?right_pad(8, ".oO")}]
결과
[ ]
[a ]
[ab ]
[abc ]
[abcd ]
[abcde]
[abcdef]
[abcdefg]
[abcdefgh]
[.oO.oO.o]
[aoO.oO.o]
[abO.oO.o]
[abc.oO.o]
[abcdoO.o]
- contains
FreeMarker 2.3.1 부터 지원됩니다.
파라미터가 문자열에 있으면 true 를 리턴합니다.
예
<#if "piceous"?contains("ice")>It contains "ice"</#if>
결과
It contains "ice"
- matches
"power user" built-in 입니다. regular expression(정규식) 을 모르면 무시해 주세요.
FreeMarker 2.3.1 부터 지원됩니다.
Java 2 플랫폼 1.4 이상의 버전을 사용할 때만 동작합니다.
이 built-in 은 문자열이 패턴에 해당하는지 판단합니다. 그리고 해당하는 부분 문자열의 리스트를 반환합니다. 반환되는 값은 multi-type 값입니다.
Boolean: 문자열이 패턴과 정확하게 일치하면, true. 아니면, false. 예를 들어, "fooo?matches('fo*') 는 true 지만, "fooo bar"?matches('fo*') 는 false 입니다.
예
<#if "fxo"?matches("f.?o")>Matches.<#else>Does not match.</#if>
<#assign res = "foo bar fyo"?matches("f.?o")>
<#if res>Matches.<#else>Does not match.</#if>
Matching sub-strings:
<#list res as m>
- ${m}
</#list>
결과
Matches.
Does not match.
Matching sub-strings:
- foo
- fyo
정규식이 groups (괄호) 를 포함하면, groups built-in 으로 접근할 수 있습니다.
<#assign res = "aa/rx; ab/r;"?matches("(\\w[^/]+)/([^;]+);")>
<#list res as m>
- ${m} is ${m?groups[1]} per ${m?groups[2]}
</#list>
결과
- aa/rx; is aa per rx
- ab/r; is ab per r
matches 는 생략 가능한 두 번째 파라미터 flags 를 허용합니다. 항상 정규식을 사용하기 때문에 flag r 은 지원되지 않는다는 것을 유의하십시오.
- number
숫자로 변환된 문자열. number 는 FTL 에서 직접 숫자를 명시했을 때와 같은 형식이어야 합니다. 즉, 숫자들 사이에 . 이 있는 locale independent form 이어야 한다는말입니다. 추가적으로 이 built-in 은 몇 가지 특정 표현을 인식합니다.(예: "1.23E6", "1.5e-8").
알려진 문제점: Java2 플랫폼 1.3 이전의 버전을 사용하면 이 built-in 은 숫자 앞의 + 와 과학적인 표현을 인식하지 못합니다.
- replace
문자열의 모든 특정 부분 문자열을 다른 문자열로 치환합니다. 단어를 다루지는 않습니다.
예
${"this is a car acarus"?replace("car", "bulldozer")}
결과
this is a bulldozer abulldozerus
치환은 왼쪽에서 오른쪽으로 진행됩니다.
${"aaaaa"?replace("aaa", "X")}
결과
Xaa
첫 번째 파라미터가 길이가 0인 문자열이면, 문자와 문자 사이에 두 번째 파라미터가 삽입됩니다. 예를 들어, "foo"?replace("", "|") 는 "|f|o|o|" 입니다.
replace 는 생략가능한 세 번째 파라미터인 flags parameter 를 허용합니다.
- rtf
Rich text(RTF text) 인 문자열. 즉, \ 가 \\ 로 치환되고, { 가 \{ 로 치환되고, } 가 \} 로 치환되는 문자열.
- url
FreeMarker 2.3.1 부터 지원됩니다.
URL escaping 을 거친 문자열. 모든 US-ASCII 가 아닌 문자와 URL 예약어가 %xx 로 치환되는 것을 의미합니다.
예
<#assign x = 'a/b c'>
${x?url}
결과(US-ASCII compatible charset 을 사용했다고 가정)
a%2Fb%20c
Note that it escapes all reserved URL characters (/, =, &, ...etc), so this encoding can be used for encoding query parameter values, for example:
| |||
Note
Above no HTML encoding (?htm) was needed, because URL escaping escapes all reserved HTML characters anyway. But watch: always quote the attribute value, and always with normal quotation mark ("), never with apostrophe quotation mark ('), because apostrophe quotation mark is not escaped by the URL escaping.
To do URL escaping a charset must be chosen that will be used for calculating the escaped parts (%XX). If you are HTML page author and you don't really understand this, don't worry: the programmers should configure FreeMarker so that it uses the proper charset by default (programmers: see more below...). If you are a more technical minded user, then you may want to know that the charset used is specified by the url_escaping_charset setting, that can be set in template execution time (or, preferably, earlier by the programmers). For example:
| |||
Furthermore, you can explicitly specify a charset for a single URL escaping as the parameter to the built-in:
| |||
If the url built-in has no parameter, then it will use the charset specified as the value of the url_escaping_charset setting. This setting should be set by the software that encloses FreeMarker (e.g. a Web application framework), because it is not set (null) by default. If it is not set, then FreeMarker falls back using the value of the output_encoding setting, which is also not set by default, so it is again the task of the enclosing software. If the output_encoding setting is not set either, then the parameterless url built-in can't be executed, and it will cause execution time error. Of course, the url built-in with parameter always works.
It's possible to set url_escaping_charset in the template with the setting directive, but it is bad practice, at least in true MVC applications. The output_encoding setting can't be set with the setting directive, so that's surely the task of the enclosing software. You may find more information regarding this here...
- split
한 문자열을 여러 문자열로 나눌 때 사용됩니다.
예
<#list "someMOOtestMOOtext"?split("MOO") as x>
- ${x}
</#list>
결과
- some
- test
- text
모든 분리자가 새로운 아이템 전에 사용된다고 가정하고 있다는 점에 유의하십시오.
<#list "some,,test,text,"?split(",") as x>
- "${x}"
</#list>
결과
- "some"
- ""
- "test"
- "text"
- ""
- starts_with
특정 문자열로 시작하면 true 를 반환합니다. 예를 들어, "redhead"?starts_with("red") 는 boolean true 를 반환합니다. "red"?starts_with("red") 도 true 를 반환합니다.
- string(when used with a string value)
아무 일도 하지 않고 현재의 문자열을 반환합니다. 예외는 값이 여러 가지 형태일 때 결과 값이 단순한 문자열이 된다는 것입니다. multi-typing 의 artifact 를 방지하기 위해 활용될 수 있습니다.
- trim
처음과 끝에 공백이 없는 문자열.
예
(${" green mouse "?trim})
결과
(green mouse)
- upper_case
대문자로만 이루어진 문자열. 예를 들어, "GrEen MoUsE" 는 "GREEN MOUSE" 가 됩니다.
- word_list
문자열의 모든 word 의 리스트. word 의 순서는 문자열에 나타나는 순서입니다. word 는 white-space 가 아닌 모든 문자의 연속입니다.
예
<#assign words = " a bcd, . 1-2-3"?word_list>
<#list words as word>[${word}]</#list>
결과
[a][bcd,][.][1-2-3]
- xhtml
XHTML 텍스트인 문자열. 즉, < 는 < 로, < 는 > 로, & 는 & 로, " 는 " 로, ' 는 ' 로, ' 는 ' 로 치환된 문자열.
이 built-in 과 xml built-in 의 차이는 xhtml built-in 은 ' 을 ' 대신 ' ; 로 치환하여 사용한다. 왜냐하면 오래된 몇 몇 브라우저는 ' 를 바르게 처리하지 못하기 때문이다.
- xml
XML 텍스트인 문자열. 즉, < 는 < 로, < 는 > 로, & 는 & 로, " 는 " 로, ' 는 ' 로, ' 는 ' 로 치환된 문자열.
- Common flags