2011-03-15
import/includeを使おうとするとMalformedURLExceptionが出る件
StreamSource xsl = new StreamSource("hoge.xsl");
これだとエラーになって、
StreamSource xsl = new StreamSource(new File("hoge.xsl"));
だと、ちゃんとパスが解決できる。……
Xalanのエラーメッセージが不親切すぎてストレス半端ないのでプロセッサをSaxonに切り替える
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
これだけで、おk。他のコードは共通でいい。
2011-03-10
XalanでJavaScriptを動かすときに必要なjarファイル
bsf.jar
Apache Commons BSF™ - Bean Scripting Framework
commons-logging.jar
js.jar
xalan.jar
2011-03-01
PDFBoxメモ
この方法だと画像が取れない形式のPDFがあるっぽい。XObjectは全部取ってきて、PDXObjectImageインスタンスか、PDXObjectFormインスタンスで処理を分けてやるといい。
public static void main(String[] args) throws IOException { String readFile = args[0]; FileInputStream pdfStream = new FileInputStream(readFile); PDFParser pdfParser = new PDFParser(pdfStream); pdfParser.parse(); int cnt = 0; PDDocument pdf = pdfParser.getPDDocument(); for (Iterator<PDPage> i = pdf.getDocumentCatalog().getAllPages().iterator(); i.hasNext();) { Map<String, PDXObject> objs = i.next().getResources().getXObjects(); for (Iterator<String> j = objs.keySet().iterator(); j.hasNext();) { PDXObject obj = objs.get(j.next()); if (obj instanceof PDXObjectImage) { PDXObjectImage image = (PDXObjectImage) obj; image.write2file(String.valueOf(cnt)); cnt++; } else if (obj instanceof PDXObjectForm) { PDXObjectForm form = (PDXObjectForm) obj; Map<String, PDXObjectImage> images = form.getResources().getImages(); for (Iterator<String> k = images.keySet().iterator(); k.hasNext();) { PDXObjectImage image = images.get(k.next()); image.write2file(String.valueOf(cnt)); cnt++; } } } } }
2011-02-28
system32にファイルコピーするには
WSHで簡易インストーラ作る必要があったのだけれど、FileSystemObjectでfileCopyしようとすると、権限がないとか言われて困り果てたのだが、shell.exec("cmd.exe /C copy")は通ってくれたので、助かった。
2011-01-21
デフォルトのcatalina.policyを使うとexamplesでcatalina.logにwarningが出る
2011/01/21 10:50:26 org.apache.catalina.startup.HostConfig deployDirectory INFO: Webアプリケーションディレクトリ examples を配備します 2011/01/21 10:50:26 org.apache.catalina.loader.WebappClassLoader findClass WARNING: WebappClassLoader.findClassInternal(chat.ChatServlet) security exception: access denied (java.lang.RuntimePermission accessClassInPackage.org.apache.catalina) java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.org.apache.catalina)
logが汚れて邪魔なので、examplesにpermissionを付与する。
// ========== EXAMPLE CODE PERMISSIONS =======================================
// These permissions apply to example
grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
// permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
// permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
};
2011-01-19
Tomcatで動かすWebアプリをプラグインで機能拡張可能にするためにやったこと
ここら辺を参考に。
プラグインのインターフェースを決める
とりあえず適当に決める。
priority付けてるのはプラグインが複数あったときに実行順を決めたかっただけ。
package com.example; public interface FooPlugin { public int getPriority(); public Bar execute(Bar bar); }
プラグイン読み込み管理クラスをつくる
最初URLClassLoaderで試してたんだけど、うまくいかないので、RMIClassLoaderに変更。
package com.example; import java.io.File; import java.io.IOException; import java.rmi.RMISecurityManager; import java.rmi.server.RMIClassLoader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.logging.Logger; public class FooPluginManager { private static final Logger logger = Logger.getLogger(FooPluginManager.class.getName()); private ArrayList<FooPlugin> plugins = new ArrayList<FooPlugin>(); public FooPluginManager(String pluginPath) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { logger.info(pluginPath); if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } File dir = new File(pluginPath); String[] files = dir.list(); for (int i = 0; i < files.length; i++) { if (files[i].toLowerCase().endsWith(".jar")) { File jarFile = new File(pluginPath + File.separator + files[i]); JarFile jar = new JarFile(jarFile); Manifest manifest = jar.getManifest(); Attributes attribs = manifest.getMainAttributes(); String className = attribs.getValue("Plugin-Class"); if (className != null) { className = className.trim(); Class<?> clazz = RMIClassLoader.loadClass(jarFile.toURL(), className); logger.info("load... " + className); Object obj = clazz.newInstance(); plugins.add((FooPlugin) obj); } } } } public ArrayList<FooPlugin> sort() { Collections.sort(plugins, new Comparator<FooPlugin>() { public int compare(FooPlugin a, FooPlugin b) { if (a.getPriority() < b.getPriority()) return -1; if (a.getPriority() > b.getPriority()) return 1; return a.getClass().getCanonicalName().compareTo(b.getClass().getCanonicalName()); } }); for (Iterator<FooPlugin> iter = plugins.iterator(); iter.hasNext();) { logger.info("sort... " + iter.next().getClass().getCanonicalName()); } return plugins; } }
プラグインを書く
2個くらい書いてみる。
package com.example; import com.example.Bar; import com.example.FooPlugin; public class FooPluginImpl1 implements FooPlugin { private static final int priority = 2; public int getPriority() { return priority; } public Bar execute(Bar bar) { return bar; } }
package com.example; import com.example.Bar; import com.example.FooPlugin; public class FooPluginImpl2 implements FooPlugin { private static final int priority = 1; public int getPriority() { return priority; } public Bar execute(Bar bar) { return bar; } }
マニフェストを書いてjarファイルをつくる
EclipseのExport機能を使ってjarファイルをつくる。(任意のマニフェストを指定できる。)
p1.mf
Manifest-Version: 1.0 Plugin-Class: com.example.FooPluginImpl1
p2.mf
Manifest-Version: 1.0 Plugin-Class: com.example.FooPluginImpl2
つくった二つのjarファイルをどこか適当に配置する。
「C:\jakarta-tomcat-6.0\webapps\foo\WEB-INF\plugins」に置いた。
メインプログラム
とりあえず読み込んでソートだけしてみる。
FooPluginManager pm = new FooPluginManager("C:\\jakarta-tomcat-6.0\\webapps\\foo\\WEB-INF\\plugins"); ArrayList<FooPlugin> plugins = pm.sort();
jakarta-tomcat-6.0/conf/catalina.policyの変更
とりあえずゆるゆるで。
// ========== FOO CODE PERMISSIONS =======================================
// These permissions apply to foo
grant codeBase "file:${catalina.home}/webapps/foo/WEB-INF/classes/-" {
permission java.security.AllPermission;
};
// These permissions apply to plugin
grant codeBase "file:${catalina.home}/webapps/foo/WEB-INF/plugins/-" {
permission java.security.AllPermission;
};
Tomcat起動引数を追加
デフォルトだとcatalina.policyは使われず、JREのlib/security/java.policyが使われる。-securityオプションを付けるとcatalina.policyを使うようになるとTomcatのドキュメントにあったんだけど、実際に試すとそんなコマンドはないとか言われて困り果てたところ、RE: Simple Security Manager how to ? というのを見つけた。
Configure -> [Java] タブ -> Java Options
-Djava.security.manager -Djava.security.policy=C:\jakarta-tomcat-6.0\conf\catalina.policy
おわり
ログで動作確認。
2011/01/19 10:54:17 com.example.FooPluginManager <init> INFO: C:\jakarta-tomcat-6.0\webapps\foo\WEB-INF\plugins 2011/01/19 10:54:17 com.example.FooPluginManager <init> INFO: load... com.example.FooPluginImpl1 2011/01/19 10:54:17 com.example.FooPluginManager <init> INFO: load... com.example.FooPluginImpl2 2011/01/19 10:54:17 com.example.FooPluginManager sort INFO: sort... com.example.FooPluginImpl2 2011/01/19 10:54:17 com.example.FooPluginManager sort INFO: sort... com.example.FooPluginImpl1
そのほか読んだリソース
2011-01-16
放置していたtumblrを再動させつつあるので、やっつけbookmarklet書いた。
選択範囲からそれっぽい引用HTMLを生成
javascript:(function(d,t,s,r,f){t.appendChild(d.createTextNode(['<blockquote%20title="'+document.title+'"%20cite="'+location.href+'"><dl>','<dt>'+f(s.shift())+'</dt>',(s.length>0?'<dd><pre>'+s.map(function(v){v=f(v);v=v.replace(r,'<a%20href="$1;">$1;</a>');return%20v}).join('\n')+'</pre></dd>\n':'')+'</dl></blockquote>'].join('\n')));with(t.style){position='fixed';bottom=left=0;zIndex=999;width='90%';height='9em'}d.body.appendChild(t);t.addEventListener('blur',function(){this.parentNode.removeChild(this)},false);t.select()})(document,document.createElement('textarea'),getSelection().toString().split(/\n/).filter(function(v)v),/(https?:\/\/[\-_.!~*\'()\w;\/?:\@&=+\$,%#]+)/g,function(s)s.replace(/^\s+|\s+$/,''))
cite属性値からanchor要素を生成
昔からあるやつです。僕はFirefoxを使っていて、CSSの擬似要素でcontent:attr(cite)とかされてても嬉しくないので。
javascript:(function(d,q){Array.prototype.slice.apply(q('blockquote,q')).forEach(function(b){b.appendChild(d.createTextNode(b.cite))})})(document,function(q)document.querySelectorAll(q))
2010-12-10
僕の Ado
ado.wsc
こういうのを書いて ado.wsc で保存して、右クリックで COM 登録して使ってる。
GUID は GUIDの生成 - Ci.nsIZIGOROu - Mozilla 拡張機能勉強会 でやると便利ですよ。
saveFile メソッドは utf-8n 用。 ADODB.Streamオブジェクトを使ってBOMなしUTF-8のファイルを作成する方法 - 大人になったら肺呼吸
2010-10-14
ENTITY使ってますか
全国のXMLerの皆さん、ENTITY使ってますか。DTDをそらで書ける皆さんなら当然使ってますよね。たとえば、Androidの設定ファイルなんかでも、
main.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE LinearLayout [ <!ENTITY padding '10dp'> <!ENTITY view.text ' <TextView android:text="copy" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="&padding;" /> '> ]> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:id="@+id/list_view_select" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="&padding;" /> <Spinner android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="&padding;" /> <RatingBar android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="&padding;" /> <EditText android:hint="コメント" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="&padding;" /> &view.text; &view.text; &view.text; &view.text; </LinearLayout>
paddingの共通値に使ってみたり、Viewを複製してみたり、
strings.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources [ <!ENTITY serv 'http://localhost/'> ]> <resources> <string name="app_name">Layout</string> <string name="url_hoge">&serv;hoge</string> <string name="url_piyo">&serv;piyo</string> <string name="url_fuga">&serv;fuga</string> <string name="text_view_camera">カメラ</string> <string name="text_view_camera_role">カメラロール</string> </resources>
文字列の共通部分とかにも! 簡単でしょ?


