select-test
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <title>テスト</title> <style> body { font-size: 9pt; color: #000000; background-color:#ffffff; } </style> <script> function setSelect(obj, target, defaultIndex) { var element = document.getElementById(target); for (var i=0;i<element.options.length;i++) { if (obj.value == element.options[i].value) { element.options[i].selected = "true"; return; } } obj.value = ""; element.options[defaultIndex].selected = "true"; } function selectChange(val, target) { document.getElementById(target).value = val; } </script> </head> <body> <input type="text" id="text" maxlength="1" onblur="setSelect(this, 'select', 0)"/> <select id="select" onChange="selectChange(this.value, 'text')"> <option value=" " selected></option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> </body> </html>
rest-manager
rest.csv
2010/10/05,テストさん,15:15,15:30,テストだよ。, 2010/10/05,テストさん,15:30,16:00,テストだよ。,
RestViewer.html
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <title>休憩管理ビューワー</title> <style> body { font-size: 9pt; color: #000000; background-color:#ffffff; } select { font-size: 9pt; color: #000000; } .button1 { width: 80px; font-weight: bold; } .button2 { width: 120px; font-weight: bold; } .table { border: 1px solid black; } .table-header1 { font-size: 9pt; font-weight: normal; text-align: center; background-color: #9999ff; } .table-record1 { border: 1px solid black; font-size:9pt; background-color: #ffffff; } .table-record2 { border: 1px solid black; font-size: 9pt; background-color: #ccccff; } .table-data1 { border-bottom: 1px solid black; border-right: 1px solid black; font-size:9pt; } .title1 { font-weight: bold; font-size: 12pt; color: #ffffff; text-decoration: underline; background-color: #9999ff; padding: 2pt 2pt 2pt 2pt; } .title-background-color { background-color: #6666ff; } </style> <script> var baseDir = ""; var tempPath = location.pathname; var path = tempPath.split("/"); for (i=0; i<path.length-1; i++) { if (path[i] != "") { baseDir += path[i] + "/"; } } var src = src = baseDir + "rest.csv"; var fil1 = ""; var fil2 = ""; var fil3 = ""; //****************************************************************************** // // ソート // //****************************************************************************** function sort(argCol) { var sortId = ""; if (argCol.value.indexOf("▲") != -1) { argCol.value = argCol.value.replace("▲", "▼"); sortId = "-" + argCol.id } else if (argCol.value.indexOf("▼") != -1) { argCol.value = argCol.value.replace("▼", "▲"); sortId = argCol.id } else { argCol.value = "▲" + argCol.value; sortId = argCol.id } tdc.Sort = sortId; tdc.Reset(); var rs = tdc.recordset; cnt.innerText = rs.RecordCount; var presortid = document.f.presortId.value; if (presortid != "" && argCol.id != presortid) { var presort = document.all.item(presortid); presort.value = presort.value.replace("▲", ""); presort.value = presort.value.replace("▼", ""); } document.f.presortId.value = argCol.id; } //****************************************************************************** // // フィルタ // //****************************************************************************** function filter() { var fil = ""; var con = "&"; if (document.f.condition[1].checked) { con = "|"; } if (fil1 != "") { fil += fil1; } if (fil2 != "") { if (fil != "") { fil += " " + con + " "; } fil += fil2; } if (fil3 != "") { if (fil != "") { fil += " " + con + " "; } fil += fil3; } tdc.Filter = fil; tdc.Reset(); var rs = tdc.recordset; cnt.innerText = rs.RecordCount; } //****************************************************************************** // // フィルタ // //****************************************************************************** function setFilter() { var tgt1 = document.f.filterTarget1.value; var val1 = document.f.filterValue1.value; if (tgt1 != "" && val1 != "") { fil1 = "(" + tgt1 + " = *" + val1 + "*)"; } else { document.f.filterTarget1.value = ""; document.f.filterValue1.value = ""; } var tgt2 = document.f.filterTarget2.value; var val2 = document.f.filterValue2.value; if (tgt2 != "" && val2 != "") { fil2 = "(" + tgt2 + " = *" + val2 + "*)"; } else { document.f.filterTarget2.value = ""; document.f.filterValue2.value = ""; } var tgt3 = document.f.filterTarget3.value; var val3 = document.f.filterValue3.value; if (tgt3 != "" && val3 != "") { fil3 = "(" + tgt3 + " = *" + val3 + "*)"; } else { document.f.filterTarget3.value = ""; document.f.filterValue3.value = ""; } filter(); } //****************************************************************************** // // フィルタクリア // //****************************************************************************** function filterClear(argIdx) { if (argIdx == 1) { fil1 = ""; document.f.filterTarget1.value = ""; document.f.filterValue1.value = ""; } else if (argIdx == 2) { fil2 = ""; document.f.filterTarget2.value = ""; document.f.filterValue2.value = ""; } else if (argIdx == 3) { fil3 = ""; document.f.filterTarget3.value = ""; document.f.filterValue3.value = ""; } } //****************************************************************************** // // 初期表示 // //****************************************************************************** function bodyOnload() { document.f.filterTarget1.value = ""; document.f.filterValue1.value = ""; document.f.filterTarget2.value = ""; document.f.filterValue2.value = ""; document.f.filterTarget3.value = ""; document.f.filterValue3.value = ""; tdc.DataURL = src; tdc.Filter = ""; tdc.Sort = "-column1"; tdc.Reset(); var rs = tdc.recordset; cnt.innerText = rs.RecordCount; var date = new Date(); year = date.getYear(); month = date.getMonth() + 1; if (month < 10) { month = "0" + month; } day = date.getDate(); if (day < 10) { day = "0" + day; } hours = date.getHours(); minutes = date.getMinutes(); document.getElementById("date").value = year + "/" + month + "/" + day; document.getElementById("restStart").value = hours + ":" + minutes; document.getElementById("restEnd").value = hours + ":" + minutes; } //****************************************************************************** // // 再表示 // //****************************************************************************** function refresh() { tdc.DataURL = src; tdc.Reset(); var rs = tdc.recordset; cnt.innerText = rs.RecordCount; } //****************************************************************************** // // 登録 // //****************************************************************************** function append() { var appendData = document.f.elements["appendData"]; var csv = ""; for (i=0; i<appendData.length; i++) { if (appendData[i].value == "") { appendData[i].value = " "; } csv += appendData[i].value + ","; } var fso = new ActiveXObject("Scripting.FileSystemObject"); var writer = fso.OpenTextFile(src, 8); writer.WriteLine(csv); writer.Close(); refresh(); } </script> </head> <body onload="bodyOnload()"> <table width="100%"> <tr class="title-background-color"> <td class="title1" id="titleName">休憩管理</td> </tr> </table> <object id="tdc" classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value=""> <param name="CharSet" value="Shift_JIS"> </object> <form name="f"> <span>フィルタ設定</span> <select name="filterTarget1"> <option value="NoFilter"></option> <option value="column1">日付</option> <option value="column2">名前</option> <option value="column3">休憩開始</option> <option value="column4">休憩終了</option> <option value="column5">コメント</option> </select> <input type="text" name="filterValue1" size="20"> <input class="button1" type="button" name="setclear1" value="クリア" onclick="filterClear(1)"> <br> <span>フィルタ設定</span> <select name="filterTarget2"> <option value="NoFilter"></option> <option value="column1">日付</option> <option value="column2">名前</option> <option value="column3">休憩開始</option> <option value="column4">休憩終了</option> <option value="column5">コメント</option> </select> <input type="text" name="filterValue2" size="20"> <input class="button1" type="button" name="setclear2" value="クリア" onclick="filterClear(2)"> <br> <span>フィルタ設定</span> <select name="filterTarget3"> <option value="NoFilter"></option> <option value="column1">日付</option> <option value="column2">名前</option> <option value="column3">休憩開始</option> <option value="column4">休憩終了</option> <option value="column5">コメント</option> </select> <input type="text" name="filterValue3" size="20"> <input class="button1" type="button" name="setclear3" value="クリア" onclick="filterClear(3)"> <br> <span>フィルタ条件</span> <input type="radio" name="condition" id="conditionAnd" value="&" checked> <label for="conditionAnd"><span>AND</span></label> <input type="radio" name="condition" id="conditionOr" value="|"> <label for="conditionOr"><span>OR</span></label> <input class="button1" type="button" name="setfilter1" value="設 定" onclick="setFilter()"> <br> <hr> <button class="button1" onclick="tb1.previousPage()">前ページ</button> <button class="button1" onclick="tb1.nextPage()">次ページ</button> <button class="button1" onclick="refresh()">再表示</button> <input type="hidden" name="presortId" value="column1"> <span>全 </span> <span id="cnt"></span> <span> 件</span> <br> <br> <table class="table" datasrc="#tdc" id="tb1" datapagesize="10" cellspacing="0" cellpadding="3"> <thead> <tr class="table-header1"> <th class="table-data1"><input class="button2" type="button" onclick="sort(this)" id="column1" value="▼日付"></th> <th class="table-data1"><input class="button2" type="button" onclick="sort(this)" id="column2" value="名前"></th> <th class="table-data1"><input class="button2" type="button" onclick="sort(this)" id="column3" value="休憩開始"></th> <th class="table-data1"><input class="button2" type="button" onclick="sort(this)" id="column4" value="休憩終了"></th> <th class="table-data1"><input class="button2" type="button" onclick="sort(this)" id="column5" value="コメント"></th> </tr> </thead> <tr class="table-record1"> <td class="table-data1" nowrap><span datafld="column1"></span></td> <td class="table-data1"><span datafld="column2"></span></td> <td class="table-data1" nowrap><span datafld="column3"></span></td> <td class="table-data1" nowrap><span datafld="column4"></span></td> <td class="table-data1"><span datafld="column5"></span></td> </tr> </table> <br> <hr> <span style="font-family:monospace;">日付 </span><input type="text" name="appendData" id="date" value=""> <br> <span style="font-family:monospace;">名前 </span><input type="text" name="appendData" id="name" value=""> <br> <span style="font-family:monospace;">休憩開始 </span><input type="text" name="appendData" id="restStart" value=""> <br> <span style="font-family:monospace;">休憩終了 </span><input type="text" name="appendData" id="restEnd" value=""> <br> <span style="font-family:monospace;">コメント </span><input type="text" name="appendData" id="comment" value=""> <br> <button class="button1" onclick="append()">登録</button> </form> </body> </html>
jqueryをはじめる
jQuery入門(その1) (1/7):CodeZine(コードジン)
を参考にjqueryを始めてみた。
会員登録しないと全部の記事が見れないみたいだから、続きはお家で。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="ja"> <head> <title>jquery sample</title> <script src="scripts/jquery-1.3.2.min.js" type="text/javascript"></script> <script type="text/javascript"> <!-- $(function(){ $("#gdEntries").css("border", "solid 1px navy"); $(".gridalternate").css("background", "lightsteelblue"); $("#gdEntries>tbody>tr>td[id^=Pk]").css("background", "#DDFFCC"); }); $(function(){ $("input:text") .blur(function(){ $(this).css("backgroundColor", "white"); }) .focus(function(){ $(this).css("backgroundColor", "#FFCCDD"); }); $("input:button,input:submit") .click(function(event){ alert("clicked"); }); }); //--> </script> </head> <body> <table id="gdEntries"> <tr> <td>a</td> <td>b</td> </tr> <tr> <td id="Pk">c</td> <td id="Pk">d</td> </tr> </table> <table class="gridalternate"> <tr> <td>a</td><td>b</td> </tr> <tr> <td>c</td><td>d</td> </tr> </table> <input type="text"/> <input type="button" value="ボタン"/> </body> </html>
docletとpoiを使ってみる
以前のテストプチフレームワークづくりの続き。
テスト結果を比較する際に、期待する結果を記述するExcelファイルの作成を支援するツール。(あくまでベース)
こんな感じかな。
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; import com.sun.javadoc.ClassDoc; import com.sun.javadoc.MethodDoc; import com.sun.javadoc.RootDoc; public class CreateExceptSheet { enum Type { JAVA_DOC, FIELD_NAME } /** * @param root * @return */ public static boolean start(RootDoc root) { try { CreateExceptSheet ces = new CreateExceptSheet(); List<Map<Type, String>> column = ces.getColumn(root); ces.createXlsFile(column); return true; } catch (Exception e) { return false; } } /** * @param root * @return */ private List<Map<Type, String>> getColumn(RootDoc root) { List<Map<Type, String>> ret = new ArrayList<Map<Type, String>>(); for (ClassDoc clazz : root.classes()) { for (MethodDoc method : clazz.methods()) { if (method.name().matches("^get.+$")) { Map<Type, String> entry = new HashMap<Type, String>(); entry.put( Type.FIELD_NAME, method.name().replace("get","") ); entry.put( Type.JAVA_DOC, method.tags("@return")[0].text() ); ret.add(entry); } } } return ret; } /** * @param column * @throws IOException */ private void createXlsFile(List<Map<Type, String>> column) throws IOException { OutputStream xlsFile = null; try { HSSFWorkbook workBook = new HSSFWorkbook(); HSSFSheet sheet = workBook.createSheet("sample"); HSSFCellStyle style = createCellStyle(workBook); int rowCount = 0; for (Type key : Type.values()) { HSSFRow row = sheet.createRow(rowCount++); int cellCount = 0; for (Map<Type, String> entry : column) { HSSFCell cell = row.createCell(cellCount++); cell.setCellStyle(style); cell.setCellValue(entry.get(key)); } } // sheet.createFreezePane(0, 0, 0, 1); xlsFile = new FileOutputStream("except.xls"); workBook.write(xlsFile); } finally { if (xlsFile != null) { xlsFile.close(); } } } /** * @param workBook * @return */ private HSSFCellStyle createCellStyle(HSSFWorkbook workBook) { HSSFFont font = workBook.createFont(); font.setFontHeightInPoints((short) 11); font.setFontName("MS Pゴシック"); HSSFCellStyle style = workBook.createCellStyle(); style.setFont(font); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBottomBorderColor(HSSFColor.BLACK.index); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setLeftBorderColor(HSSFColor.BLACK.index); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setRightBorderColor(HSSFColor.BLACK.index); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setTopBorderColor(HSSFColor.BLACK.index); style.setFillBackgroundColor(HSSFColor.BLUE.index); return style; } }
ダイナミックプロキシを使ってみる
あるフレームワークを使って構築しているWebアプリケーションのテストクラスを作成したくて、試行錯誤している途中。
テストクラスを作成するうえでフレームワークのコアな部分の知識は必須となるから、すごく勉強になる。
目標はフレームワークに依存する部分以外は、『pure java』。
、、、でも
、、、作成途中どうしてもmockを利用しなきゃ対処できない状況に陥った。。
(自分のスキル不足かな)
でも、djUnitやeasyMockは使用したくない。
(変な意地かな)
そこで調べたら、ダイナミックプロキシが使えるかなって思って、以下のようなプチモックを提供するクラスを実装してみた。
(実際、easyMockもこれを使っているみたい)
実装内容
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; public class MockHandler implements InvocationHandler { private Object proxy; private Object targetObject = null; private Class<?> targetClass = null; private Map<Method, Object> returnValues = new HashMap<Method, Object>(); /** * コンストラクタ<br> * * @param target 起動対象クラス */ public MockHandler(Class<?> target) { if (target == null || !target.isInterface()) { throw new IllegalArgumentException("targetはinterfaceを指定してください。"); } createProxy(target); } /** * コンストラクタ * * @param target 起動対象オブジェクト */ public MockHandler(Object target) { if (target == null) { throw new IllegalArgumentException("targetを指定してください。"); } targetObject = target; createProxy(target.getClass()); } /** * プロキシインスタンスの生成をします。 * * @param target 対象クラス */ private void createProxy(Class<?> target) { targetClass = target; try { // Class<?> proxyClass = Proxy.getProxyClass(target.getClassLoader(), // new Class[] { target }); // proxy = proxyClass.getConstructor( // new Class[] { InvocationHandler.class }).newInstance( // new Object[] { this }); proxy = Proxy.newProxyInstance(target.getClassLoader(), new Class[] { target }, this); } catch (Exception e) { throw new RuntimeException(e); } } /** * プロキシインスタンスを取得します。 * * @return プロキシオブジェクト **/ public Object getProxyObject() { return proxy; } /** * 指定したメソッドの戻り値を設定します。 * * @param methodName 定義メソッド * @param returnValue 戻り値 */ public void setReturnValue(String methodName, Object returnValue) { Method[] methods = targetClass.getMethods(); for (Method method : methods) { if (method.getName().equals(methodName)) { returnValues.put(method, returnValue); } } } /** * プロキシインスタンスでメソッド呼び出しを処理し、その結果を返します。<br> * 但し、{@link mock.MockHandler#setReturnValue()}にて、 * 指定したメソッドに対して戻り値を設定している場合は、その結果を返却します。 * * @see java.lang.reflect.InvocationHandler * #invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) */ public Object invoke(Object obj, Method method, Object[] args) throws Throwable { if (returnValues.containsKey(method)) { return returnValues.get(method); } if (targetObject != null) { return method.invoke(targetObject, args); } int mod = method.getModifiers(); if (!Modifier.isAbstract(mod)) { return method.invoke(obj, args); } Class<?> retType = method.getReturnType(); if (!retType.isPrimitive()) { return retType.newInstance(); } else { if (retType.isAssignableFrom(Integer.TYPE)) { return new Integer(0); } else if (retType.isAssignableFrom(Long.TYPE)) { return new Long(0); } else if (retType.isAssignableFrom(Short.TYPE)) { return new Short((short)0); } else if (retType.isAssignableFrom(Double.TYPE)) { return new Double(0); } else if (retType.isAssignableFrom(Float.TYPE)) { return new Float(0); } else if (retType.isAssignableFrom(Boolean.TYPE)) { return new Boolean(false); } else if (retType.isAssignableFrom(Character.TYPE)) { return new Character(' '); } else if (retType.isAssignableFrom(Byte.TYPE)) { return new Byte((byte)0); } else if (retType.isAssignableFrom(Void.TYPE)) { return null; } } return null; } }
使用例
MockHandler mock = new MockHandler(List.class); mock.setReturnValue("size", 10); List list = (List) mock.getProxyObject(); System.out.println(list.size());
実行結果
10
わぉ!
これは使えそう。これでテストクラスの作成が進みそう。
AptanaStudioの日本語化
Jaxerの勉強をするために、開発環境にAptanaStudioを使うことにした。
AptantaStudioの日本語化についてのメモを残しておこう。
まず、以下のサイトから、Pleiades (プレアデス)をダウンロード。
Eclipse 日本語化 | MergeDoc Project
最新版と安定板があるけど、今回は安定板をチョイス。
ダウンロードしたzipファイルを解凍し、features、pluginフォルダをそれぞれ
AptanaStudio配下のfeatures、pluginフォルダにコピー。
AptanaStudio.iniファイルの末尾に以下の内容を追加。
-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
これで完了。