OSDN Git Service

ver0.95リリース 2011/02/21
[charactermanaj/CharacterManaJ.git] / src / charactermanaj / model / io / AbstractCharacterDataArchivedFileWriter.java
1 package charactermanaj.model.io;\r
2 \r
3 import java.awt.Color;\r
4 import java.awt.Dimension;\r
5 import java.awt.image.BufferedImage;\r
6 import java.io.File;\r
7 import java.io.IOException;\r
8 import java.io.InputStream;\r
9 import java.io.OutputStream;\r
10 import java.io.OutputStreamWriter;\r
11 import java.io.Writer;\r
12 import java.nio.charset.Charset;\r
13 import java.sql.Timestamp;\r
14 import java.util.HashMap;\r
15 import java.util.List;\r
16 import java.util.Map;\r
17 import java.util.Properties;\r
18 \r
19 import charactermanaj.graphics.io.ImageResource;\r
20 import charactermanaj.graphics.io.ImageSaveHelper;\r
21 import charactermanaj.model.AppConfig;\r
22 import charactermanaj.model.CharacterData;\r
23 import charactermanaj.model.Layer;\r
24 import charactermanaj.model.PartsCategory;\r
25 import charactermanaj.model.PartsFiles;\r
26 import charactermanaj.model.PartsIdentifier;\r
27 import charactermanaj.model.PartsManageData;\r
28 import charactermanaj.model.PartsManageDataConverter;\r
29 import charactermanaj.model.PartsSet;\r
30 import charactermanaj.model.PartsSpec;\r
31 \r
32 public abstract class AbstractCharacterDataArchivedFileWriter extends AbstractCharacterDataFileWriter {\r
33 \r
34         protected AbstractCharacterDataArchivedFileWriter(File outFile) throws IOException {\r
35                 super(outFile);\r
36         }\r
37         \r
38         protected abstract OutputStream getOutputStream() throws IOException;\r
39         \r
40         protected abstract void putNextEntry(String name, long lastModified) throws IOException;\r
41         \r
42         protected abstract void closeEntry() throws IOException;\r
43 \r
44         @Override\r
45         protected void internalWriteExportProp(Properties prop) throws IOException {\r
46                 // export prop\r
47                 putNextEntry("export-info.xml", 0);\r
48                 prop.storeToXML(getOutputStream(), "exportProp");\r
49         }\r
50 \r
51         @Override\r
52         protected void internalWriteCharacterData(CharacterData characterData)\r
53                         throws IOException {\r
54                 CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
55                 \r
56                 // character.xmlの出力\r
57                 putNextEntry("character.xml", 0);\r
58                 persist.writeXMLCharacterData(characterData, getOutputStream());\r
59                 closeEntry();\r
60                 \r
61                 // character.iniの出力\r
62                 internalWriteCharacterIni(characterData);\r
63         }\r
64 \r
65         /**\r
66          * character.iniを出力します.<br>\r
67          * @param characterData キャラクターデータ\r
68          * @throws IOException 出力に失敗した場合\r
69          */\r
70         protected void internalWriteCharacterIni(CharacterData characterData) throws IOException {\r
71                 StringBuilder buf = new StringBuilder();\r
72 \r
73                 buf.append("; created by charactermanaj "\r
74                                 + new Timestamp(System.currentTimeMillis()) + "\r\n");\r
75                 \r
76                 buf.append("[Size]\r\n");\r
77                 Dimension dim = characterData.getImageSize();\r
78                 if (dim == null) {\r
79                         dim = new Dimension(300, 400);\r
80                 }\r
81                 buf.append("size_x=" + dim.width + "\r\n");\r
82                 buf.append("size_y=" + dim.height + "\r\n");\r
83 \r
84                 buf.append("\r\n");\r
85                 buf.append("[Parts]\r\n");\r
86                 \r
87                 Map<String, String> partsMap = new HashMap<String, String>();\r
88                 for (PartsCategory partsCategory : characterData.getPartsCategories()) {\r
89                         String categoryId = partsCategory.getCategoryId();\r
90                         partsMap.put(categoryId, "");\r
91                 }\r
92                 \r
93                 Map<String, PartsSet> partsSets = characterData.getPartsSets();\r
94                 PartsSet partsSet = partsSets.get(characterData.getDefaultPartsSetId());\r
95                 if (partsSet == null && !partsSets.isEmpty()) {\r
96                         // デフォルトのパーツセットが指定されていない場合は、どれか1つを選択する.\r
97                         partsSet = partsSets.values().iterator().next();\r
98                 }\r
99                 if (partsSet != null) {\r
100                         for (Map.Entry<PartsCategory, List<PartsIdentifier>> entry : partsSet\r
101                                         .entrySet()) {\r
102                                 PartsCategory partsCategory = entry.getKey();\r
103                                 StringBuilder partsNames = new StringBuilder();\r
104                                 for (PartsIdentifier partsIdentifier : entry.getValue()) {\r
105                                         if (partsNames.length() > 0) {\r
106                                                 partsNames.append(",");\r
107                                         }\r
108                                         partsNames.append(partsIdentifier.getPartsName());\r
109                                 }\r
110                                 String categoryId = partsCategory.getCategoryId();\r
111                                 partsMap.put(categoryId, partsNames.toString());\r
112                         }\r
113                 }\r
114                 for (PartsCategory partsCategory : characterData.getPartsCategories()) {\r
115                         String categoryId = partsCategory.getCategoryId();\r
116                         String partsNames = partsMap.get(categoryId);\r
117                         buf.append(categoryId + "=" + partsNames + "\r\n");\r
118                 }\r
119 \r
120                 // 色情報はすべてダミー(character.iniは色情報を省略しても問題ないようだが、一応)\r
121                 buf.append("\r\n");\r
122                 buf.append("[Color]\r\n");\r
123                 buf.append("hair_rgb=0\r\n");\r
124                 buf.append("hair_gray=0\r\n");\r
125                 buf.append("eye_rgb=0\r\n");\r
126                 buf.append("eye_gray=0\r\n");\r
127                 buf.append("skin_rgb=0\r\n");\r
128                 buf.append("skin_gray=0\r\n");\r
129                 buf.append("body_rgb=0\r\n");\r
130                 buf.append("body_gray=0\r\n");\r
131 \r
132                 // UTF16LEで出力する.\r
133                 internalWriteTextUTF16LE("character.ini", buf.toString());\r
134         }\r
135         \r
136         @Override\r
137         protected void internalWriteTextUTF16LE(String name, String contents) throws IOException {\r
138                 if (contents == null) {\r
139                         contents = "";\r
140                 }\r
141 \r
142                 // LFまたはCR改行であればCR/LF改行に変換.\r
143                 contents = contents.replace("\r\n", "\n");\r
144                 contents = contents.replace("\r", "\n");\r
145                 contents = contents.replace("\n", "\r\n");\r
146                 \r
147                 putNextEntry(name, 0);\r
148                 OutputStream os = getOutputStream();\r
149                 os.write((byte) 0xff);\r
150                 os.write((byte) 0xfe);\r
151                 os.flush();\r
152                 Writer wr = new OutputStreamWriter(os, Charset.forName("UTF-16LE")) {\r
153                         @Override\r
154                         public void close() throws IOException {\r
155                                 // ZipのOutputStreamをクローズしてはならないため\r
156                                 // OutputStreamWriter自身はクローズは呼び出さない.\r
157                                 flush();\r
158                                 closeEntry();\r
159                         }\r
160                 };\r
161                 try {\r
162                         wr.append(contents);\r
163                         wr.flush();\r
164                 } finally {\r
165                         wr.close();\r
166                 }\r
167         }\r
168         \r
169         @Override\r
170         protected void internalWriteSamplePicture(BufferedImage samplePicture)\r
171                         throws IOException {\r
172                 putNextEntry("preview.png", 0);\r
173                 ImageSaveHelper imageSaveHelper = new ImageSaveHelper();\r
174                 imageSaveHelper.savePicture(samplePicture, Color.white, getOutputStream(), "image/png", null);\r
175                 closeEntry();\r
176         }\r
177         \r
178         @Override\r
179         protected void internalWritePartsImages(\r
180                         Map<PartsIdentifier, PartsSpec> partsImages) throws IOException {\r
181                 AppConfig appConfig = AppConfig.getInstance();\r
182                 byte[] buf = new byte[appConfig.getJarTransferBufferSize()];\r
183                 \r
184                 for (Map.Entry<PartsIdentifier, PartsSpec> entry : partsImages.entrySet()) {\r
185                         PartsIdentifier partsIdentifier = entry.getKey();\r
186                         PartsSpec partsSpec = entry.getValue();\r
187                         PartsFiles partsFiles = partsSpec.getPartsFiles();\r
188                         \r
189                         for (Map.Entry<Layer, ImageResource> imageEntry : partsFiles.entrySet()) {\r
190                                 Layer layer = imageEntry.getKey();\r
191                                 ImageResource imageResource = imageEntry.getValue();\r
192 \r
193                                 String name = layer.getDir() + "/" + partsIdentifier.getPartsName() + ".png";\r
194                                 name = name.replace("//", "/");\r
195                                 \r
196                                 putNextEntry(name, imageResource.lastModified());\r
197                                 OutputStream os = getOutputStream();\r
198                                 InputStream is = imageResource.openStream();\r
199                                 try {\r
200                                         int rd;\r
201                                         while ((rd = is.read(buf)) >= 0) {\r
202                                                 os.write(buf, 0, rd);\r
203                                         }\r
204                                 } finally {\r
205                                         is.close();\r
206                                 }\r
207                                 closeEntry();\r
208                         }\r
209                 }\r
210         }\r
211         \r
212         @Override\r
213         protected void internalWritePartsManageData(\r
214                         Map<PartsIdentifier, PartsSpec> partsImages) throws IOException {\r
215                 \r
216                 PartsManageDataConverter partsManageDataConverter = new PartsManageDataConverter();\r
217                 \r
218                 for (Map.Entry<PartsIdentifier, PartsSpec> entry : partsImages.entrySet()) {\r
219                         PartsIdentifier partsIdentifier = entry.getKey();\r
220                         PartsSpec partsSpec = entry.getValue();\r
221                         partsManageDataConverter.convert(partsIdentifier, partsSpec);\r
222                 }\r
223                 \r
224                 PartsManageData partsManageData = partsManageDataConverter.getPartsManageData();\r
225                 CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
226 \r
227                 putNextEntry("parts-info.xml", 0);\r
228                 persist.savePartsManageData(partsManageData, getOutputStream());\r
229                 closeEntry();\r
230         }\r
231 }\r