001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.csv; 014 015import java.io.*; 016import java.util.*; 017 018import org.apache.juneau.*; 019import org.apache.juneau.collections.*; 020import org.apache.juneau.serializer.*; 021 022/** 023 * Session object that lives for the duration of a single use of {@link CsvSerializer}. 024 * 025 * <p> 026 * This class is NOT thread safe. 027 * It is typically discarded after one-time use although it can be reused within the same thread. 028 */ 029public final class CsvSerializerSession extends WriterSerializerSession { 030 031 /** 032 * Create a new session using properties specified in the context. 033 * 034 * @param ctx 035 * The context creating this session object. 036 * The context contains all the configuration settings for this object. 037 * @param args 038 * Runtime arguments. 039 * These specify session-level information such as locale and URI context. 040 * It also include session-level properties that override the properties defined on the bean and 041 * serializer contexts. 042 */ 043 protected CsvSerializerSession(CsvSerializer ctx, SerializerSessionArgs args) { 044 super(ctx, args); 045 } 046 047 @Override /* SerializerSession */ 048 protected final void doSerialize(SerializerPipe pipe, Object o) throws IOException, SerializeException { 049 try (Writer w = pipe.getWriter()) { 050 ClassMeta<?> cm = getClassMetaForObject(o); 051 Collection<?> l = null; 052 if (cm.isArray()) { 053 l = Arrays.asList((Object[])o); 054 } else { 055 l = (Collection<?>)o; 056 } 057 // TODO - Doesn't support DynaBeans. 058 if (l.size() > 0) { 059 ClassMeta<?> entryType = getClassMetaForObject(l.iterator().next()); 060 if (entryType.isBean()) { 061 BeanMeta<?> bm = entryType.getBeanMeta(); 062 int i = 0; 063 for (BeanPropertyMeta pm : bm.getPropertyMetas()) { 064 if (pm.canRead()) { 065 if (i++ > 0) 066 w.append(','); 067 append(w, pm.getName()); 068 } 069 } 070 w.append('\n'); 071 for (Object o2 : l) { 072 i = 0; 073 BeanMap<?> bean = toBeanMap(o2); 074 for (BeanPropertyMeta pm : bm.getPropertyMetas()) { 075 if (pm.canRead()) { 076 if (i++ > 0) 077 w.append(','); 078 append(w, pm.get(bean, pm.getName())); 079 } 080 } 081 w.append('\n'); 082 } 083 } 084 } 085 } 086 } 087 088 private static void append(Writer w, Object o) throws IOException { 089 if (o == null) 090 w.append("null"); 091 else { 092 String s = o.toString(); 093 boolean mustQuote = false; 094 for (int i = 0; i < s.length() && ! mustQuote; i++) { 095 char c = s.charAt(i); 096 if (Character.isWhitespace(c) || c == ',') 097 mustQuote = true; 098 } 099 if (mustQuote) 100 w.append('"').append(s).append('"'); 101 else 102 w.append(s); 103 } 104 } 105 106 //----------------------------------------------------------------------------------------------------------------- 107 // Other methods 108 //----------------------------------------------------------------------------------------------------------------- 109 110 @Override /* Session */ 111 public OMap toMap() { 112 return super.toMap() 113 .a("CsvSerializerSession", new DefaultFilteringOMap() 114 ); 115 } 116}