1 package charactermanaj.model.io;
3 import java.io.BufferedInputStream;
5 import java.io.FileFilter;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.OutputStream;
12 import java.util.logging.Level;
13 import java.util.logging.Logger;
15 import charactermanaj.model.CharacterData;
16 import charactermanaj.model.IndependentPartsSetInfo;
17 import charactermanaj.model.IndependentWorkingSet;
18 import charactermanaj.model.PartsColorInfo;
19 import charactermanaj.model.PartsIdentifier;
20 import charactermanaj.model.PartsSet;
21 import charactermanaj.model.WorkingSet;
22 import charactermanaj.util.FileUtilities;
23 import charactermanaj.util.UserData;
24 import charactermanaj.util.UserDataFactory;
31 public class WorkingSetPersist {
36 private static final Logger logger = Logger
37 .getLogger(WorkingSetPersist.class.getName());
42 private static final String WORKINGSET_FILE_SUFFIX = "workingset.xml";
44 private static final WorkingSetPersist singletion = new WorkingSetPersist();
46 private final UserDataFactory userDataFactory = UserDataFactory.getLocalInstance();
48 public static WorkingSetPersist getInstance() {
53 * すべてのワーキングセットをクリアする.<br>
55 public void removeAllWorkingSet() {
56 File dir = userDataFactory.getSpecialDataDir("foo-" + WORKINGSET_FILE_SUFFIX);
57 if (dir.exists() && dir.isDirectory()) {
58 File[] files = dir.listFiles(new FileFilter() {
59 public boolean accept(File pathname) {
60 return pathname.isFile() && pathname.getName().endsWith(WORKINGSET_FILE_SUFFIX);
64 logger.log(Level.WARNING, "dir access failed. " + dir);
67 for (File file : files) {
68 logger.log(Level.INFO, "remove file: " + file);
70 FileUtilities.delete(file);
71 } catch (Exception ex) {
72 logger.log(Level.WARNING, "failed to remove file: " + file, ex);
84 public void removeWorkingSet(CharacterData cd) {
85 UserData workingSetXmlData = userDataFactory.getMangledNamedUserData(
86 cd.getDocBase(), WORKINGSET_FILE_SUFFIX);
87 if (workingSetXmlData != null && workingSetXmlData.exists()) {
88 logger.log(Level.INFO, "remove file: " + workingSetXmlData);
89 workingSetXmlData.delete();
95 * ワーキングセットインスタンスには、あらかじめ全て設定しておく必要がある.<br>
102 public void saveWorkingSet(WorkingSet workingSet) throws IOException {
103 if (workingSet == null) {
104 throw new IllegalArgumentException();
106 CharacterData characterData = workingSet.getCharacterData();
107 if (characterData == null) {
108 throw new IllegalArgumentException("character-data must be set.");
111 // XML形式でのワーキングセットの保存
112 UserData workingSetXmlData = userDataFactory.getMangledNamedUserData(
113 characterData.getDocBase(), WORKINGSET_FILE_SUFFIX);
114 OutputStream outstm = workingSetXmlData.getOutputStream();
116 WorkingSetXMLWriter workingSetXmlWriter = new WorkingSetXMLWriter();
117 workingSetXmlWriter.writeWorkingSet(workingSet, outstm);
126 * @param characterData
128 * @return ワーキングセット、なければnull
129 * @throws IOException
132 public WorkingSet loadWorkingSet(CharacterData characterData)
134 if (characterData == null) {
135 throw new IllegalArgumentException();
137 // XML形式でのワーキングセットの復元
138 UserData workingSetXmlData = userDataFactory.getMangledNamedUserData(
139 characterData.getDocBase(), WORKINGSET_FILE_SUFFIX);
140 if (workingSetXmlData == null || !workingSetXmlData.exists()) {
145 // キャラクターデータと関連づけられていないワーキングセットデータを取得する
146 IndependentWorkingSet workingSet2;
148 InputStream is = workingSetXmlData.openStream();
150 WorkingSetXMLReader WorkingSetXMLReader = new WorkingSetXMLReader();
151 workingSet2 = WorkingSetXMLReader.loadWorkingSet(is);
157 // 現在のキャラクターデータと照合する。
158 URI docBase = characterData.getDocBase();
160 && !docBase.equals(workingSet2.getCharacterDocBase())) {
162 logger.log(Level.INFO, "docBase missmatch");
165 String sig = characterData.toSignatureString();
166 if (!sig.equals(workingSet2.getCharacterDataSig())) {
168 logger.log(Level.INFO, "character data structure missmatch");
172 // 現在のキャラクターデータに関連づけられているワーキングセットとして転記する
174 WorkingSet ws = new WorkingSet();
175 ws.setCharacterData(characterData);
176 ws.setCharacterDataRev(characterData.getRev());
177 ws.setCharacterDocBase(docBase);
179 ws.setLastUsedExportDir(workingSet2.getLastUsedExportDir());
180 ws.setLastUsedSaveDir(workingSet2.getLastUsedSaveDir());
183 Map<PartsIdentifier, PartsColorInfo> partsColorInfoMap = characterData
184 .getPartsColorManager().getPartsColorInfoMap();
185 workingSet2.createCompatible(characterData, partsColorInfoMap);
186 ws.setPartsColorInfoMap(partsColorInfoMap);
189 IndependentPartsSetInfo partsSetInfo = workingSet2.getCurrentPartsSet();
190 if (partsSetInfo != null) {
191 PartsSet partsSet = IndependentPartsSetInfo.convertPartsSet(
192 partsSetInfo, characterData, false);
193 ws.setCurrentPartsSet(partsSet);
196 IndependentPartsSetInfo lastUsePresetPartsInfo = workingSet2
197 .getLastUsePresetParts();
198 if (lastUsePresetPartsInfo != null
199 && lastUsePresetPartsInfo.getId() != null
200 && lastUsePresetPartsInfo.getId().trim().length() > 0) {
201 PartsSet lastUsePresetParts = IndependentPartsSetInfo
202 .convertPartsSet(lastUsePresetPartsInfo,
203 characterData, false);
204 ws.setLastUsePresetParts(lastUsePresetParts);
208 ws.setWallpaperInfo(workingSet2.getWallpaperInfo());
210 ws.setViewPosition(workingSet2.getViewPosition());
211 ws.setWindowRect(workingSet2.getWindowRect());
217 * 古いワーキングセットについて、すでに本体データが削除されている場合はワーキングセットも削除する。
219 * 生きている場合は、ワーキングセットの検査日時を表すために更新日時を現在日時に設定しなおす。
220 * @param expireDate 判定対象となる日時、それ以前のもののみ判定を行う。
222 public void purge(final long expireDate) {
223 final String XML_SUFFIX = "-" + WORKINGSET_FILE_SUFFIX;
225 UserDataFactory userDataFactory = UserDataFactory.getLocalInstance();
226 File dir = userDataFactory.getSpecialDataDir(XML_SUFFIX);
228 File[] xmls = dir.listFiles(new FileFilter() {
230 public boolean accept(File pathname) {
231 return pathname.isFile() && pathname.getName().endsWith(XML_SUFFIX)
232 && pathname.lastModified() < expireDate && pathname.length() > 0;
236 logger.log(Level.WARNING, "workingset-dir access failed.");
240 for (File xmlFile : xmls) {
242 WorkingSetXMLReader reader = new WorkingSetXMLReader();
243 IndependentWorkingSet ws;
244 InputStream is = new BufferedInputStream(new FileInputStream(xmlFile));
246 ws = reader.loadWorkingSet(is);
251 URI docBase = ws.getCharacterDocBase();
252 if (docBase.getScheme().equals("file")) {
253 File characterXml = new File(docBase);
254 if (!characterXml.exists()) {
255 // キャラクター定義XMLが存在しない = 削除されたキャラクターデータ
256 logger.log(Level.INFO, "remove amandone workingset: " + xmlFile + ", docBase=" + docBase);
259 // チェック済みであることを示すためにXMLの更新日時を現在時刻にする
260 xmlFile.setLastModified(System.currentTimeMillis());
264 } catch (Exception ex) {
265 logger.log(Level.WARNING, "file access failed. " + xmlFile, ex);