これでいいのかしら。。
public static Key allocateId(AsyncDatastoreService ds, String kind)
throws NullPointerException {
if (ds == null) {
throw new NullPointerException("The ds parameter must not be null.");
}
if (kind == null) {
throw new NullPointerException(
"The kind parameter must not be null.");
}
String ns = NamespaceManager.get();
if (ns == null) {
ns = "";
}
String cacheKey = "!"+ns+":"+kind;
Iterator<Key> keys = keysCache.get(cacheKey);
if (keys != null && keys.hasNext()) {
return keys.next();
}
keys =
FutureUtil
.getQuietly(allocateIdsAsync(ds, kind, KEY_CACHE_SIZE))
.iterator();
keysCache.put(cacheKey, keys);
return keys.next();
}
[appengine][slim3] DatastoreUtil#allocateIdがNamespaceに対応するように修正 はコメントを受け付けていません
listプロパティにInMemoryInCriterionを適用するとエラーになるので修正。
これでいいのかしら。。
public boolean accept(Object model) {
Object v = convertValueForDatastore(attributeMeta.getValue(model));
for (Object o : value) {
if (v instanceof Collection<?>) {
for (Object v2: (Collection<?>)v) {
if (compareValue(v2, o) == 0) {
return true;
}
}
} else {
if (compareValue(v, o) == 0) {
return true;
}
}
}
return false;
}
[appengine][slim3]InMemoryInCriterionがlistプロパティでも動作するように修正 はコメントを受け付けていません
appengineでJSON-RPCサーバーのようなものを作りたいときなど ServletRequest#getInputStream()で取得できるInputStreamを使いたい場合があります。ところがslim3のcontrollerでこれをやろうとするとInputStreamのIllegalStateExceptionが発生します。
Jettyや大概のサーブレットサーバーは getInputStreamとgetParameter(s)を同時には使えないようです。
JSON-RPCならslim3のcontrollerは使う必要ないじゃんといえばそれまでなのですができれば慣れているもので全てやってしまいたいというのも事実。そこで以下のようなworkaroundで回避します。
- StreamFilterを作って、そこでServletRequestをWrapperクラスに置き換える (一番最初にこのFilterが動くようにする)
- RequestWrapperでは getInputStreamをoverrideし、Streamを再利用可能にする
なお、このworkaroundは http://d.hatena.ne.jp/machi_pon/20090120/1232420325 にて紹介されているやり方とほぼ同じです。(ナイスポストありがとうございました!)
public class StreamFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
request = new BufferedServletRequestWrapper( req );
chain.doFilter(request, response);
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
public class BufferedServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] buffer;
public BufferedServletRequestWrapper(HttpServletRequest request) throws IOException {
super( request );
InputStream is = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buff[] = new byte[ 1024 ];
int read;
while( ( read = is.read( buff ) ) > 0 ) {
baos.write( buff, 0, read );
}
this.buffer = baos.toByteArray();
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new BufferedServletInputStream( this.buffer );
}
}
public class BufferedServletInputStream extends ServletInputStream {
private ByteArrayInputStream inputStream;
public BufferedServletInputStream(byte[] buffer) {
this.inputStream = new ByteArrayInputStream( buffer );
}
@Override
public int available() throws IOException {
return inputStream.available();
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return inputStream.read( b, off, len );
}
}
slim3のcontrollerでServletInputStreamを使いたいとき はコメントを受け付けていません