grails doc --pdf で日本語を使う

Grails 2.5

itext-2.0.8を使用しているため、itext-asianは古いものを使用する。とりあえず下記をダウンロードしてlibに入れる。
http://www.java2s.com/Code/JarDownload/iTextAsian/iTextAsian.jar.zip

フォントキャッシュを書き換えてからgrails doc --pdfさせるスクリプトを作成する。

grails create-script doc-pdf

scripts/DocPdf.groovy

import org.xhtmlrenderer.pdf.ITextRenderer

import com.lowagie.text.pdf.BaseFont

includeTargets << grailsScript("_GrailsDocs")

setDefaultTarget("docPdf")

target(docPdf:"grails doc-pdf") {

    // BaseFont.fontCacheを初期化
    new ITextRenderer() 

    // fontCacheをすべて日本語フォントにしてしまう
    def bf = BaseFont.createFont('HeiseiMin-W3', 'UniJIS-UCS2-H', BaseFont.NOT_EMBEDDED)
    BaseFont.fontCache.keySet().each {
        BaseFont.fontCache.put(it, bf)
    }

    // --pdfを指定したときと同じように動作させる
    argsMap.pdf = true

    // 丸投げ
    depends(docs)
}

実行する。

grails doc-pdf

コード部分はゴシック、文章は明朝とかいろいろあると思うけど、とっかかりはこんな感じ。

thymeleaf with grails 3.0.1

build.gradle

dependencies {
    compile "org.springframework.boot:spring-boot-starter-logging"
    compile "org.springframework.boot:spring-boot-starter-actuator"
    compile "org.springframework.boot:spring-boot-autoconfigure"
    compile "org.springframework.boot:spring-boot-starter-tomcat"
    compile "org.springframework.boot:spring-boot-starter-thymeleaf" // add
    :

application.yml

environments:
    development:
        dataSource:
            dbCreate: create-drop
            url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
        spring:
            thymeleaf:
                prefix: file:./grails-app/views
                suffix: .html
                templateMode: HTML5
                cacheable: false
        :
    production:
        :
        spring:
            thymeleaf:
                prefix: classpath:/WEB-INF/grails-app/views
                suffix: .html
                templateMode: HTML5
                cacheable: true

resources.groovy

beans = {
    
    grailsThymeleafViewResolver(sample.GrailsThymeleafViewResolver) {
        characterEncoding = 'utf8'
        templateEngine = ref('templateEngine')
    }
    
    springConfig.addAlias 'thymeleafViewResolver', 'grailsThymeleafViewResolver'
    springConfig.addAlias 'jspViewResolver', 'thymeleafViewResolver'
}

sample.GrailsThymeleafViewResolver

package sample

import org.grails.web.servlet.view.GrailsViewResolver
import org.grails.web.util.WebUtils
import org.springframework.web.servlet.View
import org.thymeleaf.spring4.view.ThymeleafViewResolver

class GrailsThymeleafViewResolver
    extends ThymeleafViewResolver
        implements GrailsViewResolver {

    @Override
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        return super.resolveViewName(WebUtils.addViewPrefix(viewName), locale);
    }
}

grails-app/views/layouts/main.html

<!doctype html>
<html lang="en" class="no-js"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:th="http://www.thymeleaf.org"
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <title layout:replace="title">Grails</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="../../assets/stylesheets/application.css" th:href="@{/assets/application.css}" />
        <script type="text/javascript" src="../../assets/javascripts/application.js" th:src="@{/assets/application.js}" ></script>
    </head>
    <body>
        <div id="grailsLogo" role="banner"><a href="http://grails.org"><img src="../../assets/images/grails_logo.png" alt="Grails" th:src="@{/assets/grails_logo.png}" /></a></div>
        <div layout:fragment="content"></div>
        <div class="footer" role="contentinfo"></div>
        <div id="spinner" class="spinner" style="display:none;" th:text="#{spinner.alt}">Loading&hellip;</div>
    </body>
</html>

grails-app/views/book/create.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:th="http://www.thymeleaf.org"
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
  layout:decorator="/layouts/main">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title layout:replace="title" th:text="#{default.create.label(#{book.label})}">Create Book</title>
    </head>
    <body>
    <div layout:fragment="content">
    <p th:text="#{default.create.label(#{book.label})}">ppp</p>
    :

RubyCAS-Client-Rails Single Sign Out

Rails 4のアプリでCASを使ってSSOしたいのでRubyCAS-Client-Railsを使ってチャレンジ。

rubycas/rubycas-client-rails · GitHub

現時点ではリポジトリから引っ張らないと動かない

echo "gem 'rubycas-client', :git => 'git://github.com/rubycas/rubycas-client.git'" >> Gemfile
echo "gem 'rubycas-client-rails', :git => 'git://github.com/rubycas/rubycas-client-rails.git'" >> Gemfile
bundle install

現状ではSingle Sign Outの処理がRails4に対応していないので修正する

lib/rubycas-client-rails.rb

   312           # Rails 3.0
    313           ## required_sess_store = ActiveRecord::SessionStore
    314           ## current_sess_store  = ::Rails.application.config.session_store
    315 
    316           # Rails 4.0
    317           required_sess_store = ActionDispatch::Session::ActiveRecordStore
    318           current_sess_store  = ::Rails.application.config.session_store
    319 
    320           if current_sess_store == required_sess_store
    321             session_id = read_service_session_lookup(si)
    322 
    323             if session_id
    324               session = current_sess_store.session_class.find_by_session_id(session_id)

Grails Spring Security Cas 2.0-RC1 Single Sign Out

Spring Security CAS 2.0-RC1はSpring Security Core 2.0-RC2に依存しているが、コンパイルが通らないためSpring Security Core 2.0-RC4を使用する。

grails-app/conf/BuildConfig.groovy

:
grails.project.dependency.resolution = {
    :
    repositories {
        :
        mavenRepo "http://repo.spring.io/milestone/"
    }
    :
    plugins {
        :
        compile ":spring-security-core:2.0-RC4"
        compile ":spring-security-cas:2.0-RC1"
    }
}

設定は以下の通り。

grails-app/conf/Config.groovy

:
grails.plugin.springsecurity.cas.active = true
grails.plugin.springsecurity.cas.serverUrlPrefix = 'http://localhost:8081/cas' // required
grails.plugin.springsecurity.cas.serverUrlEncoding = 'UTF-8'
grails.plugin.springsecurity.cas.loginUri = '/login'
grails.plugin.springsecurity.cas.sendRenew = false
grails.plugin.springsecurity.cas.serviceUrl = 'http://localhost:8080/myapp/j_spring_cas_security_check' // required
grails.plugin.springsecurity.cas.key = 'myapp' // should be changed
grails.plugin.springsecurity.cas.artifactParameter = 'ticket'
grails.plugin.springsecurity.cas.serviceParameter = 'service'
grails.plugin.springsecurity.cas.filterProcessesUrl = '/j_spring_cas_security_check'
grails.plugin.springsecurity.cas.proxyCallbackUrl = 'http://localhost:8080/myapp/secure/receptor' // required
grails.plugin.springsecurity.cas.proxyReceptorUrl = '/secure/receptor' // required

// single sign out
grails.plugin.springsecurity.cas.useSingleSignout = true
grails.plugin.springsecurity.useSessionFixationPrevention = false // default true

重要なのはuseSessionFixationPreventionを設定するところ。
SessionFixationProtectionStrategyが有効だと、SingleSignOutHandlerのsessionMappingStorageにsessionを維持できないため、LogoutRequestをもらってもsessionを破棄できない。
https://jira.spring.io/browse/SEC-1658
https://issues.jasig.org/browse/CASC-216

Directory.Existsの判定がおかしい

使ったのはMicrosoft Visual C# 2010 Express

問題

  1. ソリューションエクスプローラーのプロジェクトを右クリック→プロパティ→設定タブ
  2. キー"dir"の値に存在するフォルダのパスを設定
  3. dirTextBox.Text = Properties.Settings.Default.dir;
  4. Directory.Exists(dirTextBox.Text)
  5. →False

原因
- デフォルトでは設定タブの内容がutf-8

  • どうもShift_JISの\をコピペでUTF-8に張り付けたのがだめだったらしい

対策
- 生成されたapp.configを開き、エンコードShift_JISに変更

ひどすぎる

Cassandraを入れる

Cassandra - http://cassandra.apache.org/

ダウンロード&インストール

[root@centos6 src]# wget http://ftp.riken.jp/net/apache/cassandra/1.1.4/apache-cassandra-1.1.4-bin.tar.gz
[root@centos6 src]# tar xvfz apache-cassandra-1.1.4-bin.tar.gz
[root@centos6 src]# mv apache-cassandra-1.1.4 /usr/local/lib/apache-cassandra
[root@centos6 src]# cd /usr/local/lib/cassandra/
[root@centos6 cassandra]# mkdir /var/lib/cassandra/data
[root@centos6 cassandra]# mkdir /var/lib/cassandra/commitlog
[root@centos6 cassandra]# mkdir /var/lib/cassandra/saved_caches

動作確認

サーバーを起動する。

[root@centos6 cassandra]# bin/cassandra -f

クライアントCLIを起動して動作を確認する。

[root@centos6 cassandra]# bin/cassandra-cli
[default@unknown] create keyspace DEMO;
[default@unknown] use DEMO;
[default@DEMO] create column family Users;
[default@DEMO] set Users[utf8('1234')][utf8('name')] = utf8('scott');
[default@DEMO] set Users[utf8('1234')][utf8('password')] = utf8('tiger');
[default@DEMO] get Users[utf8('1234')];
=> (column=6e616d65, value=scott, timestamp=1345710238634000)
=> (column=70617373776f7264, value=tiger, timestamp=1345710271270000)
Returned 2 results.
Elapsed time: 105 msec(s).

わからないことはhelpする

[default@DEMO] help

MongoDBを入れる

MongoDB - http://www.mongodb.org/

ダウンロード&インストール

[root@centos6 ~]# cd /usr/local/src
[root@centos6 src]# wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.7.tgz
[root@centos6 src]# tar xvfz mongodb-linux-i686-2.0.7.tgz 
[root@centos6 src]# mv mongodb-linux-i686-2.0.7 /usr/local/lib/mongodb
[root@centos6 src]# cd /usr/local/lib/mongodb

インストール後の設定

[root@centos6 mongodb]# mkdir -p /var/lib/mongodb/data
[root@centos6 mongodb]# vi bin/mongodb.config

/usr/local/lib/mongodb/bin/mongodb.config

dbpath=/var/lib/mongodb/data

起動

[root@centos6 mongodb]# bin/mongod --config bin/mongodb.config 
bash: bin/mongod: /lib/ld-linux.so.2: bad ELF interpreter: そのようなファイルやディレクトリはありません

ないなら入れてリトライ。

[root@centos6 mongodb]# yum install ld-linux.so.2
[root@centos6 mongodb]# bin/mongod --config bin/mongodb.config 
bin/mongod: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

・・・ないなら入れてリトライ。

[root@centos6 mongodb]# yum install libstdc++.so.6
[root@centos6 mongodb]# bin/mongod --config bin/mongodb.config 
:
Thu Aug 23 14:22:57 [initandlisten] waiting for connections on port 27017

おk。

参考:
MongoDBの薄い本