OSDN Git Service

パーツ管理情報クラスのXMLの読み書き部を別クラスに分離
authorseraphy <seraphy@5b6e9025-a2e8-4882-b233-f889982098c5>
Sun, 6 Oct 2013 17:58:35 +0000 (17:58 +0000)
committerseraphy <seraphy@5b6e9025-a2e8-4882-b233-f889982098c5>
Sun, 6 Oct 2013 17:58:35 +0000 (17:58 +0000)
git-svn-id: https://svn.sourceforge.jp/svnroot/charactermanaj/trunk@57 5b6e9025-a2e8-4882-b233-f889982098c5

src/charactermanaj/model/io/AbstractCharacterDataArchiveFile.java
src/charactermanaj/model/io/AbstractCharacterDataArchivedFileWriter.java
src/charactermanaj/model/io/CharacterDataPersistent.java
src/charactermanaj/model/io/CharacterDataXMLWriter.java
src/charactermanaj/model/io/ImportModel.java
src/charactermanaj/model/io/PartsInfoXMLReader.java [new file with mode: 0644]
src/charactermanaj/model/io/PartsInfoXMLWriter.java [new file with mode: 0644]
src/charactermanaj/ui/PartsManageDialog.java
src/charactermanaj/ui/ProfileListManager.java

index 5e53a13..b227ca5 100644 (file)
@@ -921,9 +921,8 @@ public abstract class AbstractCharacterDataArchiveFile
 \r
                InputStream is = content.openStream();\r
                try {\r
-                       CharacterDataPersistent persist = CharacterDataPersistent\r
-                                       .getInstance();\r
-                       partsManageData = persist.loadPartsManageData(is);\r
+                       PartsInfoXMLReader xmlReader = new PartsInfoXMLReader();\r
+                       partsManageData = xmlReader.loadPartsManageData(is);\r
                } finally {\r
                        is.close();\r
                }\r
index e4174a3..c92fd1a 100644 (file)
@@ -225,10 +225,10 @@ public abstract class AbstractCharacterDataArchivedFileWriter extends AbstractCh
                }\r
                \r
                PartsManageData partsManageData = partsManageDataConverter.getPartsManageData();\r
-               CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
+               PartsInfoXMLWriter xmlWriter = new PartsInfoXMLWriter();\r
 \r
                putNextEntry("parts-info.xml", 0);\r
-               persist.savePartsManageData(partsManageData, getOutputStream());\r
+               xmlWriter.savePartsManageData(partsManageData, getOutputStream());\r
                closeEntry();\r
        }\r
 }\r
index fc3c8e3..188d214 100644 (file)
@@ -10,20 +10,14 @@ import java.io.FileOutputStream;
 import java.io.IOException;\r
 import java.io.InputStream;\r
 import java.io.OutputStream;\r
-import java.io.OutputStreamWriter;\r
 import java.net.URI;\r
 import java.net.URL;\r
-import java.nio.charset.Charset;\r
 import java.text.SimpleDateFormat;\r
 import java.util.ArrayList;\r
-import java.util.Collection;\r
 import java.util.Collections;\r
 import java.util.Date;\r
-import java.util.HashMap;\r
 import java.util.Iterator;\r
-import java.util.LinkedList;\r
 import java.util.List;\r
-import java.util.Locale;\r
 import java.util.NoSuchElementException;\r
 import java.util.concurrent.ExecutionException;\r
 import java.util.concurrent.ExecutorService;\r
@@ -35,35 +29,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Level;\r
 import java.util.logging.Logger;\r
 \r
-import javax.xml.XMLConstants;\r
-import javax.xml.namespace.NamespaceContext;\r
-import javax.xml.parsers.DocumentBuilder;\r
-import javax.xml.parsers.DocumentBuilderFactory;\r
-import javax.xml.parsers.ParserConfigurationException;\r
-import javax.xml.parsers.SAXParser;\r
-import javax.xml.parsers.SAXParserFactory;\r
-import javax.xml.transform.OutputKeys;\r
-import javax.xml.transform.Transformer;\r
-import javax.xml.transform.TransformerConfigurationException;\r
-import javax.xml.transform.TransformerException;\r
-import javax.xml.transform.TransformerFactory;\r
-import javax.xml.transform.dom.DOMSource;\r
-import javax.xml.transform.stream.StreamResult;\r
-import javax.xml.validation.Schema;\r
-import javax.xml.validation.SchemaFactory;\r
-import javax.xml.xpath.XPath;\r
-import javax.xml.xpath.XPathFactory;\r
-\r
-import org.w3c.dom.Attr;\r
-import org.w3c.dom.Document;\r
-import org.w3c.dom.Element;\r
 import org.w3c.dom.Node;\r
 import org.w3c.dom.NodeList;\r
-import org.xml.sax.Attributes;\r
-import org.xml.sax.ErrorHandler;\r
-import org.xml.sax.SAXException;\r
-import org.xml.sax.SAXParseException;\r
-import org.xml.sax.helpers.DefaultHandler;\r
 \r
 import charactermanaj.graphics.io.FileImageResource;\r
 import charactermanaj.graphics.io.ImageLoader;\r
@@ -72,10 +39,7 @@ import charactermanaj.graphics.io.LoadedImage;
 import charactermanaj.model.AppConfig;\r
 import charactermanaj.model.CharacterData;\r
 import charactermanaj.model.Layer;\r
-import charactermanaj.model.PartsAuthorInfo;\r
 import charactermanaj.model.PartsCategory;\r
-import charactermanaj.model.PartsManageData;\r
-import charactermanaj.model.PartsManageData.PartsKey;\r
 import charactermanaj.ui.MainFrame;\r
 import charactermanaj.util.DirectoryConfig;\r
 import charactermanaj.util.FileNameNormalizer;\r
@@ -105,6 +69,9 @@ public class CharacterDataPersistent {
         */\r
        private final CharacterDataXMLReader characterDataXmlReader = new CharacterDataXMLReader();\r
 \r
+       /**\r
+        * キャラクターデータを格納したXMLのライタ\r
+        */\r
        private final CharacterDataXMLWriter characterDataXmlWriter = new CharacterDataXMLWriter();\r
 \r
        /**\r
@@ -117,96 +84,6 @@ public class CharacterDataPersistent {
         */\r
        public static final String VERSION_SIG_1_0 = "1.0";\r
 \r
-       /**\r
-        * キャラクター定義XMLファイルの名前空間\r
-        */\r
-       public static final String NS = "http://charactermanaj.sourceforge.jp/schema/charactermanaj";\r
-\r
-       /**\r
-        * パーツ定義XMLファイルの名前空間\r
-        */\r
-       public static final String NS_PARTSDEF = "http://charactermanaj.sourceforge.jp/schema/charactermanaj-partsdef";\r
-\r
-       /**\r
-        * キャラクター定義XML用のスキーマ定義リソース名\r
-        */\r
-       private static final String CHARACTER_XML_SCHEMA = "/schema/character.xsd";\r
-\r
-       /**\r
-        * キャラクター定義XML用のスキーマ定義リソース名\r
-        */\r
-       private static final String CHARACTER_XML_SCHEMA_0_8 = "/schema/0.8/character.xsd";\r
-\r
-       /**\r
-        * パーツセット定義XMLのスキーマ定義リソース名\r
-        */\r
-       private static final String PARTSSET_XML_SCHEMA = "/schema/partsset.xsd";\r
-\r
-       /**\r
-        * パーツセット定義XMLのスキーマ定義リソース名\r
-        */\r
-       private static final String PARTSSET_XML_SCHEMA_0_8 = "/schema/0.8/partsset.xsd";\r
-\r
-       /**\r
-        * XMLのデータ形式.<br>\r
-        * SchemaのバリデージョンチェックとDOMの解析を始める前にSAXで流し込んで、\r
-        * 最初のエレメント名や使用している名前空間、バージョンを読み込んで、 スキーマをきりかえられるようにするためのもの.\r
-        * \r
-        * @author seraphy\r
-        */\r
-       public static class DocInfo {\r
-\r
-               private String firstElementName;\r
-\r
-               private String version;\r
-\r
-               private String namespace;\r
-\r
-               public void setFirstElementName(String firstElementName) {\r
-                       this.firstElementName = firstElementName;\r
-               }\r
-\r
-               /**\r
-                * 最初の要素のqName\r
-                * \r
-                * @return\r
-                */\r
-               public String getFirstElementName() {\r
-                       return firstElementName;\r
-               }\r
-\r
-               public void setNamespace(String namespace) {\r
-                       this.namespace = namespace;\r
-               }\r
-\r
-               public void setVersion(String version) {\r
-                       this.version = version;\r
-               }\r
-\r
-               /**\r
-                * 最初の要素に指定されているxmlns属性の値\r
-                * \r
-                * @param namespace\r
-                */\r
-               public String getNamespace() {\r
-                       return namespace;\r
-               }\r
-\r
-               /**\r
-                * 最初の要素に指定されているversion属性の値\r
-                * \r
-                * @return\r
-                */\r
-               public String getVersion() {\r
-                       return version;\r
-               }\r
-\r
-               @Override\r
-               public String toString() {\r
-                       return firstElementName + " /version: " + version + " /namespace:"\r
-                                       + namespace;\r
-               }\r
-       }\r
 \r
        /**\r
         * プロファイルの列挙時のエラーハンドラ.<br>\r
@@ -227,36 +104,6 @@ public class CharacterDataPersistent {
        }\r
 \r
        /**\r
-        * プロファイル列挙時のデフォルトのエラーハンドラ.<br>\r
-        * 標準エラー出力にメッセージをプリントするだけで何もしない.<br>\r
-        */\r
-       public static final ProfileListErrorHandler DEFAULT_ERROR_HANDLER = new ProfileListErrorHandler() {\r
-               public void occureException(File baseDir, Throwable ex) {\r
-                       logger.log(Level.WARNING, "invalid profile. :" + baseDir, ex);\r
-               }\r
-       };\r
-\r
-       /**\r
-        * スキーマのキャッシュ.\r
-        */\r
-       private HashMap<String, Schema> schemaMap = new HashMap<String, Schema>();\r
-\r
-       /**\r
-        * JAXPで使用するデフォルトのエラーハンドラ\r
-        */\r
-       private static final ErrorHandler errorHandler = new ErrorHandler() {\r
-               public void error(SAXParseException exception) throws SAXException {\r
-                       throw exception;\r
-               }\r
-               public void fatalError(SAXParseException exception) throws SAXException {\r
-                       throw exception;\r
-               }\r
-               public void warning(SAXParseException exception) throws SAXException {\r
-                       throw exception;\r
-               }\r
-       };\r
-\r
-       /**\r
         * プライベートコンストラクタ.<br>\r
         * シングルトン実装であるため、一度だけ呼び出される.\r
         */\r
@@ -678,59 +525,6 @@ public class CharacterDataPersistent {
                return characterData;\r
        }\r
 \r
-\r
-       /**\r
-        * XMLの最初の要素と、その要素の属性にあるversionとxmlnsを取得して返す.<br>\r
-        * XMLとして不正などの理由で取得できない場合はnullを返す.<br>\r
-        * 読み込みそのものに失敗した場合は例外を返す.<br>\r
-        * \r
-        * @param is\r
-        *            XMLコンテンツと想定される入力ストリーム\r
-        * @return DocInfo情報、もしくはnull\r
-        * @throws IOException\r
-        *             読み込みに失敗した場合\r
-        */\r
-       public DocInfo readDocumentType(InputStream is) throws IOException {\r
-\r
-               SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();\r
-               SAXParser saxParser;\r
-               try {\r
-                       saxParser = saxParserFactory.newSAXParser();\r
-               } catch (ParserConfigurationException ex) {\r
-                       throw new RuntimeException("JAXP Configuration Exception.", ex);\r
-               } catch (SAXException ex) {\r
-                       throw new RuntimeException("JAXP Configuration Exception.", ex);\r
-               }\r
-\r
-               try {\r
-                       final DocInfo[] result = new DocInfo[1];\r
-                       saxParser.parse(is, new DefaultHandler() {\r
-                               private int elmCount = 0;\r
-                               @Override\r
-                               public void startElement(String uri, String localName,\r
-                                               String qName, Attributes attributes)\r
-                                               throws SAXException {\r
-                                       if (elmCount == 0) {\r
-                                               String version = attributes.getValue("version");\r
-                                               String namespace = attributes.getValue("xmlns");\r
-                                               DocInfo docInfo = new DocInfo();\r
-                                               docInfo.setFirstElementName(qName);\r
-                                               docInfo.setVersion(version);\r
-                                               docInfo.setNamespace(namespace);\r
-                                               result[0] = docInfo;\r
-                                       }\r
-                                       elmCount++;\r
-                               }\r
-                       });\r
-                       return result[0];\r
-\r
-               } catch (SAXException ex) {\r
-                       logger.log(Level.INFO, "character.xml check failed.", ex);\r
-               }\r
-               return null;\r
-       }\r
-\r
-\r
        protected void saveCharacterDataToXML(CharacterData characterData)\r
                        throws IOException {\r
                if (characterData == null) {\r
@@ -781,7 +575,7 @@ public class CharacterDataPersistent {
                UserData favoritesData = getFavoritesUserData(characterData);\r
                OutputStream os = favoritesData.getOutputStream();\r
                try {\r
-                       saveFavorites(characterData, os);\r
+                       characterDataXmlWriter.saveFavorites(characterData, os);\r
 \r
                } finally {\r
                        os.close();\r
@@ -799,61 +593,6 @@ public class CharacterDataPersistent {
                return new FileUserData(new File(characterDir, "favorites.xml"));\r
        }\r
 \r
-       protected void saveFavorites(CharacterData characterData,\r
-                       OutputStream outstm) throws IOException {\r
-               if (characterData == null || outstm == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-\r
-               Document doc;\r
-               try {\r
-                       DocumentBuilderFactory factory = DocumentBuilderFactory\r
-                                       .newInstance();\r
-                       factory.setNamespaceAware(true);\r
-                       DocumentBuilder builder = factory.newDocumentBuilder();\r
-                       doc = builder.newDocument();\r
-\r
-               } catch (ParserConfigurationException ex) {\r
-                       throw new RuntimeException("JAXP Configuration Exception.", ex);\r
-               }\r
-\r
-               Element root = doc.createElementNS(NS, "partssets");\r
-\r
-               root.setAttribute("xmlns:xml", XMLConstants.XML_NS_URI);\r
-               root.setAttribute("xmlns:xsi",\r
-                               "http://www.w3.org/2001/XMLSchema-instance");\r
-               root.setAttribute("xsi:schemaLocation", NS + " partsset.xsd");\r
-               doc.appendChild(root);\r
-\r
-               // presetsのelementを構築する.(Presetは除く)\r
-               characterDataXmlWriter.writePartsSetElements(doc, root, characterData,\r
-                               false, true);\r
-\r
-               // output xml\r
-               TransformerFactory txFactory = TransformerFactory.newInstance();\r
-               txFactory.setAttribute("indent-number", Integer.valueOf(4));\r
-               Transformer tfmr;\r
-               try {\r
-                       tfmr = txFactory.newTransformer();\r
-               } catch (TransformerConfigurationException ex) {\r
-                       throw new RuntimeException("JAXP Configuration Failed.", ex);\r
-               }\r
-               tfmr.setOutputProperty(OutputKeys.INDENT, "yes");\r
-\r
-               // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504745\r
-               final String encoding = "UTF-8";\r
-               tfmr.setOutputProperty("encoding", encoding);\r
-               try {\r
-                       tfmr.transform(new DOMSource(doc), new StreamResult(\r
-                                       new OutputStreamWriter(outstm, Charset.forName(encoding))));\r
-\r
-               } catch (TransformerException ex) {\r
-                       IOException ex2 = new IOException("XML Convert failed.");\r
-                       ex2.initCause(ex);\r
-                       throw ex2;\r
-               }\r
-       }\r
-\r
 \r
        /**\r
         * お気に入り(Favorites)を読み込む.<br>\r
@@ -1007,97 +746,10 @@ public class CharacterDataPersistent {
                };\r
        }\r
 \r
-       protected Schema loadSchema(DocInfo docInfo) throws IOException {\r
-               if (docInfo == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-\r
-               String schemaName = null;\r
-               if ("character".equals(docInfo.getFirstElementName())) {\r
-                       if ("http://com.exmaple/charactermanaj".equals(docInfo\r
-                                       .getNamespace())) {\r
-                               schemaName = CHARACTER_XML_SCHEMA_0_8;\r
-                       } else if ("http://charactermanaj.sourceforge.jp/schema/charactermanaj"\r
-                                       .equals(docInfo.getNamespace())) {\r
-                               schemaName = CHARACTER_XML_SCHEMA;\r
-                       }\r
-               } else if ("partssets".equals(docInfo.getFirstElementName())) {\r
-                       if ("http://com.exmaple/charactermanaj".equals(docInfo\r
-                                       .getNamespace())) {\r
-                               schemaName = PARTSSET_XML_SCHEMA_0_8;\r
-                       } else if ("http://charactermanaj.sourceforge.jp/schema/charactermanaj"\r
-                                       .equals(docInfo.getNamespace())) {\r
-                               schemaName = PARTSSET_XML_SCHEMA;\r
-                       }\r
-               }\r
-               if (schemaName == null) {\r
-                       throw new IOException("unsupported namespace: " + docInfo);\r
-               }\r
-\r
-               Schema schema = schemaMap.get(schemaName);\r
-               if (schema != null) {\r
-                       return schema;\r
-               }\r
-\r
-               URL schemaURL = null;\r
-               try {\r
-                       SchemaFactory schemaFactory = SchemaFactory\r
-                                       .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);\r
-                       schemaFactory.setErrorHandler(errorHandler);\r
-                       schemaURL = getEmbeddedResourceURL(schemaName);\r
-                       schema = schemaFactory.newSchema(schemaURL);\r
-                       schemaMap.put(schemaName, schema);\r
-                       return schema;\r
-\r
-               } catch (Exception ex) {\r
-                       throw new RuntimeException("schema creation failed. :" + schemaURL,\r
-                                       ex);\r
-               }\r
-       }\r
-\r
        protected URL getEmbeddedResourceURL(String schemaName) {\r
                return this.getClass().getResource(schemaName);\r
        }\r
 \r
-       protected XPath createXPath(DocInfo docInfo) {\r
-               if (docInfo == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-\r
-               final String namespace;\r
-               if (docInfo.getNamespace() != null\r
-                               && docInfo.getNamespace().length() > 0) {\r
-                       namespace = docInfo.getNamespace();\r
-               } else {\r
-                       namespace = NS;\r
-               }\r
-\r
-               XPathFactory xpathFactory = XPathFactory.newInstance();\r
-               XPath xpath = xpathFactory.newXPath();\r
-               xpath.setNamespaceContext(new NamespaceContext() {\r
-                       public String getNamespaceURI(String prefix) {\r
-                               if (prefix == null) {\r
-                                       throw new IllegalArgumentException();\r
-                               }\r
-                               if (prefix.equals("pre")) {\r
-                                       return namespace;\r
-                               }\r
-                               if (prefix.equals("xml")) {\r
-                                       return XMLConstants.XML_NS_URI;\r
-                               }\r
-                               return XMLConstants.NULL_NS_URI;\r
-                       }\r
-                       public Iterator<?> getPrefixes(String namespaceURI) {\r
-                               throw new UnsupportedOperationException();\r
-                       }\r
-\r
-                       public String getPrefix(String namespaceURI) {\r
-                               throw new UnsupportedOperationException();\r
-                       }\r
-               });\r
-               return xpath;\r
-       }\r
-\r
        /**\r
         * サンプルピクチャを読み込む.<br>\r
         * ピクチャが存在しなければnullを返す. キャラクター定義がValidでない場合は常にnullを返す.<br>\r
@@ -1217,453 +869,7 @@ public class CharacterDataPersistent {
                }\r
        }\r
 \r
-       /**\r
-        * パーツ管理情報をDocBaseと同じフォルダ上のparts-info.xmlに書き出す.<br>\r
-        * XML生成中に失敗した場合は既存の管理情報は残される.<br>\r
-        * (管理情報の書き込み中にI/O例外が発生した場合は管理情報は破壊される.)<br>\r
-        * \r
-        * @param docBase\r
-        *            character.xmlの位置\r
-        * @param partsManageData\r
-        *            パーツ管理情報\r
-        * @throws IOException\r
-        *             出力に失敗した場合\r
-        */\r
-       public void savePartsManageData(URI docBase, PartsManageData partsManageData)\r
-                       throws IOException {\r
-               if (docBase == null || partsManageData == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-\r
-               if (!"file".equals(docBase.getScheme())) {\r
-                       throw new IOException("ファイル以外はサポートしていません: " + docBase);\r
-               }\r
-               File docBaseFile = new File(docBase);\r
-               File baseDir = docBaseFile.getParentFile();\r
-\r
-               // データからXMLを構築してストリームに出力する.\r
-               // 完全に成功したXMLのみ書き込むようにするため、一旦バッファする。\r
-               ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
-               try {\r
-                       savePartsManageData(partsManageData, bos);\r
-               } finally {\r
-                       bos.close();\r
-               }\r
-\r
-               // バッファされたXMLデータを実際のファイルに書き込む\r
-               File partsInfoXML = new File(baseDir, "parts-info.xml");\r
-               FileOutputStream os = new FileOutputStream(partsInfoXML);\r
-               try {\r
-                       os.write(bos.toByteArray());\r
-               } finally {\r
-                       os.close();\r
-               }\r
-       }\r
-\r
-       /**\r
-        * パーツ管理情報をXMLとしてストリームに書き出す.<br>\r
-        * \r
-        * @param partsManageData\r
-        *            パーツ管理データ\r
-        * @param outstm\r
-        *            出力先ストリーム\r
-        * @throws IOException\r
-        *             出力に失敗した場合\r
-        */\r
-       public void savePartsManageData(PartsManageData partsManageData,\r
-                       OutputStream outstm) throws IOException {\r
-               if (partsManageData == null || outstm == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-\r
-               Document doc;\r
-               try {\r
-                       DocumentBuilderFactory factory = DocumentBuilderFactory\r
-                                       .newInstance();\r
-                       factory.setNamespaceAware(true);\r
-                       DocumentBuilder builder = factory.newDocumentBuilder();\r
-                       doc = builder.newDocument();\r
-\r
-               } catch (ParserConfigurationException ex) {\r
-                       throw new RuntimeException("JAXP Configuration Exception.", ex);\r
-               }\r
-\r
-               Locale locale = Locale.getDefault();\r
-               String lang = locale.getLanguage();\r
-\r
-               Element root = doc.createElementNS(NS_PARTSDEF, "parts-definition");\r
-\r
-               root.setAttribute("xmlns:xml", XMLConstants.XML_NS_URI);\r
-               root.setAttribute("xmlns:xsi",\r
-                               "http://www.w3.org/2001/XMLSchema-instance");\r
-               root.setAttribute("xsi:schemaLocation", NS_PARTSDEF\r
-                               + " parts-definition.xsd");\r
-               doc.appendChild(root);\r
-\r
-               // 作者情報を取得する\r
-               Collection<PartsAuthorInfo> partsAuthors = partsManageData\r
-                               .getAuthorInfos();\r
-               for (PartsAuthorInfo partsAuthorInfo : partsAuthors) {\r
-                       String author = partsAuthorInfo.getAuthor();\r
-                       if (author == null || author.length() == 0) {\r
-                               continue;\r
-                       }\r
-\r
-                       // 作者情報の登録\r
-                       Element nodeAuthor = doc.createElementNS(NS_PARTSDEF, "author");\r
-                       Element nodeAuthorName = doc.createElementNS(NS_PARTSDEF, "name");\r
-                       Attr attrLang = doc.createAttributeNS(XMLConstants.XML_NS_URI,\r
-                                       "lang");\r
-                       attrLang.setValue(lang);\r
-                       nodeAuthorName.setAttributeNodeNS(attrLang);\r
-                       nodeAuthorName.setTextContent(author);\r
-                       nodeAuthor.appendChild(nodeAuthorName);\r
-\r
-                       String homepageURL = partsAuthorInfo.getHomePage();\r
-                       if (homepageURL != null && homepageURL.length() > 0) {\r
-                               Element nodeHomepage = doc.createElementNS(NS_PARTSDEF,\r
-                                               "home-page");\r
-                               Attr attrHomepageLang = doc.createAttributeNS(\r
-                                               XMLConstants.XML_NS_URI, "lang");\r
-                               attrHomepageLang.setValue(lang);\r
-                               nodeHomepage.setAttributeNodeNS(attrHomepageLang);\r
-                               nodeHomepage.setTextContent(homepageURL);\r
-                               nodeAuthor.appendChild(nodeHomepage);\r
-                       }\r
-\r
-                       root.appendChild(nodeAuthor);\r
-\r
-                       Collection<PartsKey> partsKeys = partsManageData\r
-                                       .getPartsKeysByAuthor(author);\r
-\r
-                       // ダウンロード別にパーツキーの集約\r
-                       HashMap<String, List<PartsKey>> downloadMap = new HashMap<String, List<PartsKey>>();\r
-                       for (PartsKey partsKey : partsKeys) {\r
-                               PartsManageData.PartsVersionInfo versionInfo = partsManageData\r
-                                               .getVersionStrict(partsKey);\r
-                               String downloadURL = versionInfo.getDownloadURL();\r
-                               if (downloadURL == null) {\r
-                                       downloadURL = "";\r
-                               }\r
-                               List<PartsKey> partsKeyGrp = downloadMap.get(downloadURL);\r
-                               if (partsKeyGrp == null) {\r
-                                       partsKeyGrp = new ArrayList<PartsKey>();\r
-                                       downloadMap.put(downloadURL, partsKeyGrp);\r
-                               }\r
-                               partsKeyGrp.add(partsKey);\r
-                       }\r
-\r
-                       // ダウンロード別にパーツ情報の登録\r
-                       ArrayList<String> downloadURLs = new ArrayList<String>(\r
-                                       downloadMap.keySet());\r
-                       Collections.sort(downloadURLs);\r
-\r
-                       for (String downloadURL : downloadURLs) {\r
-                               List<PartsKey> partsKeyGrp = downloadMap.get(downloadURL);\r
-                               Collections.sort(partsKeyGrp);\r
-\r
-                               Element nodeDownload = doc.createElementNS(NS_PARTSDEF,\r
-                                               "download-url");\r
-                               nodeDownload.setTextContent(downloadURL);\r
-                               root.appendChild(nodeDownload);\r
-\r
-                               for (PartsKey partsKey : partsKeyGrp) {\r
-                                       PartsManageData.PartsVersionInfo versionInfo = partsManageData\r
-                                                       .getVersionStrict(partsKey);\r
-\r
-                                       Element nodeParts = doc.createElementNS(NS_PARTSDEF,\r
-                                                       "parts");\r
-\r
-                                       nodeParts.setAttribute("name", partsKey.getPartsName());\r
-                                       if (partsKey.getCategoryId() != null) {\r
-                                               nodeParts.setAttribute("category",\r
-                                                               partsKey.getCategoryId());\r
-                                       }\r
-                                       if (versionInfo.getVersion() > 0) {\r
-                                               nodeParts.setAttribute("version",\r
-                                                               Double.toString(versionInfo.getVersion()));\r
-                                       }\r
-\r
-                                       String localizedName = partsManageData\r
-                                                       .getLocalizedName(partsKey);\r
-                                       if (localizedName != null\r
-                                                       && localizedName.trim().length() > 0) {\r
-                                               Element nodeLocalizedName = doc.createElementNS(\r
-                                                               NS_PARTSDEF, "local-name");\r
-                                               Attr attrLocalizedNameLang = doc.createAttributeNS(\r
-                                                               XMLConstants.XML_NS_URI, "lang");\r
-                                               attrLocalizedNameLang.setValue(lang);\r
-                                               nodeLocalizedName\r
-                                                               .setAttributeNodeNS(attrLocalizedNameLang);\r
-                                               nodeLocalizedName.setTextContent(localizedName);\r
-                                               nodeParts.appendChild(nodeLocalizedName);\r
-                                       }\r
-\r
-                                       root.appendChild(nodeParts);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // output xml\r
-               TransformerFactory txFactory = TransformerFactory.newInstance();\r
-               txFactory.setAttribute("indent-number", Integer.valueOf(4));\r
-               Transformer tfmr;\r
-               try {\r
-                       tfmr = txFactory.newTransformer();\r
-               } catch (TransformerConfigurationException ex) {\r
-                       throw new RuntimeException("JAXP Configuration Failed.", ex);\r
-               }\r
-               tfmr.setOutputProperty(OutputKeys.INDENT, "yes");\r
-\r
-               // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504745\r
-               final String encoding = "UTF-8";\r
-               tfmr.setOutputProperty("encoding", encoding);\r
-               try {\r
-                       tfmr.transform(new DOMSource(doc), new StreamResult(\r
-                                       new OutputStreamWriter(outstm, Charset.forName(encoding))));\r
-\r
-               } catch (TransformerException ex) {\r
-                       IOException ex2 = new IOException("XML Convert failed.");\r
-                       ex2.initCause(ex);\r
-                       throw ex2;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * 指定したDocBaseと同じフォルダにあるparts-info.xmlからパーツ管理情報を取得して返す.<br>\r
-        * ファイルが存在しない場合は空のインスタンスを返す.<br>\r
-        * 返されるインスタンスは編集可能です.<br>\r
-        * \r
-        * @param docBase\r
-        *            character.xmlの位置\r
-        * @return パーツ管理情報、存在しない場合は空のインスタンス\r
-        * @throws IOException\r
-        *             読み込み中に失敗した場合\r
-        */\r
-       public PartsManageData loadPartsManageData(URI docBase) throws IOException {\r
-               if (docBase == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               if (!"file".equals(docBase.getScheme())) {\r
-                       throw new IOException("ファイル以外はサポートしていません。:" + docBase);\r
-               }\r
-               File docBaseFile = new File(docBase);\r
-               File baseDir = docBaseFile.getParentFile();\r
-\r
-               // パーツ管理情報ファイルの確認\r
-               final File partsInfoXML = new File(baseDir, "parts-info.xml");\r
-               if (!partsInfoXML.exists()) {\r
-                       // ファイルが存在しなければ空を返す.\r
-                       return new PartsManageData();\r
-               }\r
-\r
-               PartsManageData partsManageData;\r
-               InputStream is = new FileInputStream(partsInfoXML);\r
-               try {\r
-                       partsManageData = loadPartsManageData(is);\r
-               } finally {\r
-                       is.close();\r
-               }\r
-               return partsManageData;\r
-       }\r
-\r
-       public PartsManageData loadPartsManageData(InputStream is)\r
-                       throws IOException {\r
-               if (is == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-\r
-               // パーツ管理情報\r
-               final PartsManageData partsManageData = new PartsManageData();\r
-\r
-               // SAXParserの準備\r
-               SAXParser saxParser;\r
-               try {\r
-                       SAXParserFactory saxPartserFactory = SAXParserFactory.newInstance();\r
-                       saxPartserFactory.setNamespaceAware(true);\r
-                       saxParser = saxPartserFactory.newSAXParser();\r
-               } catch (Exception ex) {\r
-                       throw new RuntimeException("JAXP Configuration failed.", ex);\r
-               }\r
-\r
-               // デフォルトのロケールから言語を取得\r
-               final Locale locale = Locale.getDefault();\r
-               final String lang = locale.getLanguage();\r
-\r
-               try {\r
-                       // 要素のスタック\r
-                       final LinkedList<String> stack = new LinkedList<String>();\r
-\r
-                       // DOMではなくSAXで読み流す.\r
-                       saxParser.parse(is, new DefaultHandler() {\r
-                               private StringBuilder buf = new StringBuilder();\r
-\r
-                               private PartsAuthorInfo partsAuthorInfo;\r
-\r
-                               private String authorName;\r
-                               private String homepageURL;\r
-                               private String authorNameLang;\r
-                               private String homepageLang;\r
-                               private String downloadURL;\r
-\r
-                               private String partsLocalNameLang;\r
-                               private String partsLocalName;\r
-                               private String partsCategoryId;\r
-                               private String partsName;\r
-                               private double partsVersion;\r
-\r
-                               @Override\r
-                               public void startDocument() throws SAXException {\r
-                                       logger.log(Level.FINEST, "parts-info : start");\r
-                               }\r
-\r
-                               @Override\r
-                               public void endDocument() throws SAXException {\r
-                                       logger.log(Level.FINEST, "parts-info : end");\r
-                               }\r
-\r
-                               @Override\r
-                               public void characters(char[] ch, int start, int length)\r
-                                               throws SAXException {\r
-                                       buf.append(ch, start, length);\r
-                               }\r
-                               @Override\r
-                               public void startElement(String uri, String localName,\r
-                                               String qName, Attributes attributes)\r
-                                               throws SAXException {\r
-                                       stack.addFirst(qName);\r
-                                       int mx = stack.size();\r
-                                       if (mx >= 2 && stack.get(1).equals("parts")) {\r
-                                               if ("local-name".equals(qName)) {\r
-                                                       partsLocalNameLang = attributes.getValue(\r
-                                                                       XMLConstants.XML_NS_URI, "lang");\r
-                                               }\r
-\r
-                                       } else if (mx >= 2 && stack.get(1).equals("author")) {\r
-                                               if ("name".equals(qName)) {\r
-                                                       authorNameLang = attributes.getValue(\r
-                                                                       XMLConstants.XML_NS_URI, "lang");\r
-\r
-                                               } else if ("home-page".equals(qName)) {\r
-                                                       homepageLang = attributes.getValue(\r
-                                                                       XMLConstants.XML_NS_URI, "lang");\r
-                                               }\r
-\r
-                                       } else if ("author".equals(qName)) {\r
-                                               partsAuthorInfo = null;\r
-                                               authorName = null;\r
-                                               authorNameLang = null;\r
-                                               homepageURL = null;\r
-                                               homepageLang = null;\r
-\r
-                                       } else if ("download-url".equals(qName)) {\r
-                                               downloadURL = null;\r
-\r
-                                       } else if ("parts".equals(qName)) {\r
-                                               partsLocalName = null;\r
-                                               partsLocalNameLang = null;\r
-                                               partsCategoryId = attributes.getValue("category");\r
-                                               partsName = attributes.getValue("name");\r
-                                               String strVersion = attributes.getValue("version");\r
-                                               try {\r
-                                                       if (strVersion == null || strVersion.length() == 0) {\r
-                                                               partsVersion = 0.;\r
-\r
-                                                       } else {\r
-                                                               partsVersion = Double.parseDouble(strVersion);\r
-                                                               if (partsVersion < 0) {\r
-                                                                       partsVersion = 0;\r
-                                                               }\r
-                                                       }\r
-\r
-                                               } catch (Exception ex) {\r
-                                                       logger.log(Level.INFO,\r
-                                                                       "parts-info.xml: invalid version."\r
-                                                                                       + strVersion);\r
-                                                       partsVersion = 0;\r
-                                               }\r
-                                       }\r
-\r
-                                       buf = new StringBuilder();\r
-                               }\r
-                               @Override\r
-                               public void endElement(String uri, String localName,\r
-                                               String qName) throws SAXException {\r
-\r
-                                       int mx = stack.size();\r
-\r
-                                       if (mx >= 2 && "parts".equals(stack.get(1))) {\r
-                                               if ("local-name".equals(qName)) {\r
-                                                       if (partsLocalName == null\r
-                                                                       || lang.equals(partsLocalNameLang)) {\r
-                                                               partsLocalName = buf.toString();\r
-                                                       }\r
-                                               }\r
-\r
-                                       } else if (mx >= 2 && "author".equals(stack.get(1))) {\r
-                                               if ("name".equals(qName)) {\r
-                                                       if (authorName == null\r
-                                                                       || lang.equals(authorNameLang)) {\r
-                                                               authorName = buf.toString();\r
-                                                       }\r
-\r
-                                               } else if ("home-page".equals(qName)) {\r
-                                                       if (homepageURL == null\r
-                                                                       || lang.equals(homepageLang)) {\r
-                                                               homepageURL = buf.toString();\r
-                                                       }\r
-                                               }\r
-\r
-                                       } else if ("author".equals(qName)) {\r
-                                               logger.log(Level.FINE, "parts-info: author: "\r
-                                                               + authorName + " /homepage:" + homepageURL);\r
-                                               if (authorName != null && authorName.length() > 0) {\r
-                                                       partsAuthorInfo = new PartsAuthorInfo();\r
-                                                       partsAuthorInfo.setAuthor(authorName);\r
-                                                       partsAuthorInfo.setHomePage(homepageURL);\r
-\r
-                                               } else {\r
-                                                       partsAuthorInfo = null;\r
-                                               }\r
-\r
-                                       } else if ("download-url".equals(qName)) {\r
-                                               downloadURL = buf.toString();\r
-                                               logger.log(Level.FINE, "parts-info: download-url: "\r
-                                                               + downloadURL);\r
-\r
-                                       } else if ("parts".equals(qName)) {\r
-                                               if (logger.isLoggable(Level.FINE)) {\r
-                                                       logger.log(Level.FINE,\r
-                                                                       "parts-info.xml: parts-name: " + partsName\r
-                                                                                       + " /category: " + partsCategoryId\r
-                                                                                       + " /parts-local-name: "\r
-                                                                                       + partsLocalName + " /version:"\r
-                                                                                       + partsVersion);\r
-                                               }\r
-\r
-                                               PartsManageData.PartsVersionInfo versionInfo = new PartsManageData.PartsVersionInfo();\r
-                                               versionInfo.setVersion(partsVersion);\r
-                                               versionInfo.setDownloadURL(downloadURL);\r
 \r
-                                               PartsManageData.PartsKey partsKey = new PartsManageData.PartsKey(\r
-                                                               partsName, partsCategoryId);\r
-\r
-                                               partsManageData.putPartsInfo(partsKey, partsLocalName,\r
-                                                               partsAuthorInfo, versionInfo);\r
-\r
-                                       }\r
-                                       stack.removeFirst();\r
-                               }\r
-                       });\r
-\r
-               } catch (SAXException ex) {\r
-                       IOException ex2 = new IOException("parts-info.xml read failed.");\r
-                       ex2.initCause(ex);\r
-                       throw ex2;\r
-               }\r
-\r
-               return partsManageData;\r
-       }\r
 \r
 \r
        /**\r
index 65bbf0b..cbeff3c 100644 (file)
@@ -1,6 +1,5 @@
 package charactermanaj.model.io;\r
 \r
-import static charactermanaj.model.io.CharacterDataPersistent.NS;\r
 import static charactermanaj.model.io.CharacterDataPersistent.VERSION_SIG_1_0;\r
 \r
 import java.awt.Color;\r
@@ -42,8 +41,18 @@ import charactermanaj.model.PartsIdentifier;
 import charactermanaj.model.PartsSet;\r
 import charactermanaj.model.RecommendationURL;\r
 \r
+/**\r
+ * パーツ管理情報のXMLへの書き込み用クラス.\r
+ * \r
+ * @author seraphy\r
+ */\r
 public class CharacterDataXMLWriter {\r
 \r
+       /**\r
+        * キャラクター定義XMLファイルの名前空間\r
+        */\r
+       private static final String NS = "http://charactermanaj.sourceforge.jp/schema/charactermanaj";\r
+\r
        public void writeXMLCharacterData(CharacterData characterData,\r
                        OutputStream outstm) throws IOException {\r
                if (outstm == null || characterData == null) {\r
@@ -523,4 +532,58 @@ public class CharacterDataXMLWriter {
 \r
                return registeredPartsSetMap.size();\r
        }\r
+\r
+       public void saveFavorites(CharacterData characterData,\r
+                       OutputStream outstm) throws IOException {\r
+               if (characterData == null || outstm == null) {\r
+                       throw new IllegalArgumentException();\r
+               }\r
+\r
+               Document doc;\r
+               try {\r
+                       DocumentBuilderFactory factory = DocumentBuilderFactory\r
+                                       .newInstance();\r
+                       factory.setNamespaceAware(true);\r
+                       DocumentBuilder builder = factory.newDocumentBuilder();\r
+                       doc = builder.newDocument();\r
+\r
+               } catch (ParserConfigurationException ex) {\r
+                       throw new RuntimeException("JAXP Configuration Exception.", ex);\r
+               }\r
+\r
+               Element root = doc.createElementNS(NS, "partssets");\r
+\r
+               root.setAttribute("xmlns:xml", XMLConstants.XML_NS_URI);\r
+               root.setAttribute("xmlns:xsi",\r
+                               "http://www.w3.org/2001/XMLSchema-instance");\r
+               root.setAttribute("xsi:schemaLocation", NS + " partsset.xsd");\r
+               doc.appendChild(root);\r
+\r
+               // presetsのelementを構築する.(Presetは除く)\r
+               writePartsSetElements(doc, root, characterData, false, true);\r
+\r
+               // output xml\r
+               TransformerFactory txFactory = TransformerFactory.newInstance();\r
+               txFactory.setAttribute("indent-number", Integer.valueOf(4));\r
+               Transformer tfmr;\r
+               try {\r
+                       tfmr = txFactory.newTransformer();\r
+               } catch (TransformerConfigurationException ex) {\r
+                       throw new RuntimeException("JAXP Configuration Failed.", ex);\r
+               }\r
+               tfmr.setOutputProperty(OutputKeys.INDENT, "yes");\r
+\r
+               // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504745\r
+               final String encoding = "UTF-8";\r
+               tfmr.setOutputProperty("encoding", encoding);\r
+               try {\r
+                       tfmr.transform(new DOMSource(doc), new StreamResult(\r
+                                       new OutputStreamWriter(outstm, Charset.forName(encoding))));\r
+\r
+               } catch (TransformerException ex) {\r
+                       IOException ex2 = new IOException("XML Convert failed.");\r
+                       ex2.initCause(ex);\r
+                       throw ex2;\r
+               }\r
+       }\r
 }\r
index 0e1e708..7feda5d 100644 (file)
@@ -41,8 +41,7 @@ public class ImportModel {
        \r
        \r
        /**\r
-        * インポートもとアーカイブ.\r
-        * ロードされた場合に非nullとなる.\r
+        * インポートもとアーカイブ. ロードされた場合に非nullとなる.\r
         */\r
        private CharacterDataArchiveFile archiveFile;\r
        \r
@@ -63,13 +62,12 @@ public class ImportModel {
        private String readme;\r
        \r
        /**\r
-        * インポート先のキャラクター定義、もしくは現在のキャラクター定義のディレクトリ構成から\r
-        * 読み取ることのできるパーツのコレクション、なければ空.<br>\r
+        * インポート先のキャラクター定義、もしくは現在のキャラクター定義のディレクトリ構成から 読み取ることのできるパーツのコレクション、なければ空.<br>\r
         */\r
        private Collection<PartsImageContent> partsImageContentsMap;\r
        \r
        /**\r
-        * パーツ管理データ、なければ空 \r
+        * パーツ管理データ、なければ空\r
         */\r
        private PartsManageData partsManageData;\r
        \r
@@ -197,9 +195,13 @@ public class ImportModel {
        \r
        /**\r
         * パーツデータをプロファイルの画像ディレクトリに一括コピーする.<br>\r
-        * @param partsImageContents コピー対象のパーツデータ\r
-        * @param cd コピー先のプロファイル\r
-        * @throws IOException 失敗\r
+        * \r
+        * @param partsImageContents\r
+        *            コピー対象のパーツデータ\r
+        * @param cd\r
+        *            コピー先のプロファイル\r
+        * @throws IOException\r
+        *             失敗\r
         */\r
        public void copyPartsImageContents(\r
                        Collection<PartsImageContent> partsImageContents, CharacterData cd)\r
@@ -259,14 +261,19 @@ public class ImportModel {
        /**\r
         * パーツ管理情報を更新または作成する.<br>\r
         * パーツ管理情報がnullまたは空であれば何もしない.<br>\r
-        * そうでなければインポートするパーツに該当するパーツ管理情報を、現在のプロファイルのパーツ管理情報に追記・更新し、\r
-        * それを書き出す.<br>\r
+        * そうでなければインポートするパーツに該当するパーツ管理情報を、現在のプロファイルのパーツ管理情報に追記・更新し、 それを書き出す.<br>\r
         * インポートもとにパーツ管理情報がなく、既存にある場合、インポートしても管理情報は削除されません.(上書きセマンティクスのため)\r
-        * @param partsImageContents インポートするパーツ\r
-        * @param partsManageData パーツ管理データ\r
-        * @param current 現在のパーツ管理データを保持しているプロファイル、新規の場合はnull\r
-        * @param target 書き込み先のプロファイル\r
-        * @throws IOException 書き込みに失敗した場合\r
+        * \r
+        * @param partsImageContents\r
+        *            インポートするパーツ\r
+        * @param partsManageData\r
+        *            パーツ管理データ\r
+        * @param current\r
+        *            現在のパーツ管理データを保持しているプロファイル、新規の場合はnull\r
+        * @param target\r
+        *            書き込み先のプロファイル\r
+        * @throws IOException\r
+        *             書き込みに失敗した場合\r
         */\r
        public void updatePartsManageData(\r
                        Collection<PartsImageContent> partsImageContents,\r
@@ -282,12 +289,12 @@ public class ImportModel {
                        return;\r
                }\r
 \r
-               CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
+               PartsInfoXMLReader xmlReader = new PartsInfoXMLReader();\r
                \r
                PartsManageData mergedPartsManagedData;\r
                if (current != null && current.isValid()) {\r
                        // 現在のプロファイルからパーツ管理情報を取得する.\r
-                       mergedPartsManagedData = persist.loadPartsManageData(current.getDocBase());\r
+                       mergedPartsManagedData = xmlReader.loadPartsManageData(current.getDocBase());\r
                } else {\r
                        // 新規の場合は空\r
                        mergedPartsManagedData = new PartsManageData();\r
@@ -314,6 +321,8 @@ public class ImportModel {
                }\r
 \r
                // パーツ管理情報を更新する.\r
-               persist.savePartsManageData(target.getDocBase(), mergedPartsManagedData);\r
+               PartsInfoXMLWriter partsInfoXMLWriter = new PartsInfoXMLWriter();\r
+               partsInfoXMLWriter.savePartsManageData(target.getDocBase(),\r
+                               mergedPartsManagedData);\r
        }\r
 }\r
diff --git a/src/charactermanaj/model/io/PartsInfoXMLReader.java b/src/charactermanaj/model/io/PartsInfoXMLReader.java
new file mode 100644 (file)
index 0000000..2e810a6
--- /dev/null
@@ -0,0 +1,272 @@
+package charactermanaj.model.io;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.net.URI;\r
+import java.util.LinkedList;\r
+import java.util.Locale;\r
+import java.util.logging.Level;\r
+import java.util.logging.Logger;\r
+\r
+import javax.xml.XMLConstants;\r
+import javax.xml.parsers.SAXParser;\r
+import javax.xml.parsers.SAXParserFactory;\r
+\r
+import org.xml.sax.Attributes;\r
+import org.xml.sax.SAXException;\r
+import org.xml.sax.helpers.DefaultHandler;\r
+\r
+import charactermanaj.model.PartsAuthorInfo;\r
+import charactermanaj.model.PartsManageData;\r
+\r
+/**\r
+ * パーツ管理情報のXMLの読み込み用クラス.\r
+ * \r
+ * @author seraphy\r
+ */\r
+public class PartsInfoXMLReader {\r
+\r
+       /**\r
+        * ロガー\r
+        */\r
+       private static final Logger logger = Logger\r
+                       .getLogger(PartsInfoXMLReader.class.getName());\r
+\r
+       /**\r
+        * 指定したDocBaseと同じフォルダにあるparts-info.xmlからパーツ管理情報を取得して返す.<br>\r
+        * ファイルが存在しない場合は空のインスタンスを返す.<br>\r
+        * 返されるインスタンスは編集可能です.<br>\r
+        * \r
+        * @param docBase\r
+        *            character.xmlの位置\r
+        * @return パーツ管理情報、存在しない場合は空のインスタンス\r
+        * @throws IOException\r
+        *             読み込み中に失敗した場合\r
+        */\r
+       public PartsManageData loadPartsManageData(URI docBase) throws IOException {\r
+               if (docBase == null) {\r
+                       throw new IllegalArgumentException();\r
+               }\r
+               if (!"file".equals(docBase.getScheme())) {\r
+                       throw new IOException("ファイル以外はサポートしていません。:" + docBase);\r
+               }\r
+               File docBaseFile = new File(docBase);\r
+               File baseDir = docBaseFile.getParentFile();\r
+\r
+               // パーツ管理情報ファイルの確認\r
+               final File partsInfoXML = new File(baseDir, "parts-info.xml");\r
+               if (!partsInfoXML.exists()) {\r
+                       // ファイルが存在しなければ空を返す.\r
+                       return new PartsManageData();\r
+               }\r
+\r
+               PartsManageData partsManageData;\r
+               InputStream is = new FileInputStream(partsInfoXML);\r
+               try {\r
+                       partsManageData = loadPartsManageData(is);\r
+               } finally {\r
+                       is.close();\r
+               }\r
+               return partsManageData;\r
+       }\r
+\r
+       public PartsManageData loadPartsManageData(InputStream is)\r
+                       throws IOException {\r
+               if (is == null) {\r
+                       throw new IllegalArgumentException();\r
+               }\r
+\r
+               // パーツ管理情報\r
+               final PartsManageData partsManageData = new PartsManageData();\r
+\r
+               // SAXParserの準備\r
+               SAXParser saxParser;\r
+               try {\r
+                       SAXParserFactory saxPartserFactory = SAXParserFactory.newInstance();\r
+                       saxPartserFactory.setNamespaceAware(true);\r
+                       saxParser = saxPartserFactory.newSAXParser();\r
+               } catch (Exception ex) {\r
+                       throw new RuntimeException("JAXP Configuration failed.", ex);\r
+               }\r
+\r
+               // デフォルトのロケールから言語を取得\r
+               final Locale locale = Locale.getDefault();\r
+               final String lang = locale.getLanguage();\r
+\r
+               try {\r
+                       // 要素のスタック\r
+                       final LinkedList<String> stack = new LinkedList<String>();\r
+\r
+                       // DOMではなくSAXで読み流す.\r
+                       saxParser.parse(is, new DefaultHandler() {\r
+                               private StringBuilder buf = new StringBuilder();\r
+\r
+                               private PartsAuthorInfo partsAuthorInfo;\r
+\r
+                               private String authorName;\r
+                               private String homepageURL;\r
+                               private String authorNameLang;\r
+                               private String homepageLang;\r
+                               private String downloadURL;\r
+\r
+                               private String partsLocalNameLang;\r
+                               private String partsLocalName;\r
+                               private String partsCategoryId;\r
+                               private String partsName;\r
+                               private double partsVersion;\r
+\r
+                               @Override\r
+                               public void startDocument() throws SAXException {\r
+                                       logger.log(Level.FINEST, "parts-info : start");\r
+                               }\r
+\r
+                               @Override\r
+                               public void endDocument() throws SAXException {\r
+                                       logger.log(Level.FINEST, "parts-info : end");\r
+                               }\r
+\r
+                               @Override\r
+                               public void characters(char[] ch, int start, int length)\r
+                                               throws SAXException {\r
+                                       buf.append(ch, start, length);\r
+                               }\r
+                               @Override\r
+                               public void startElement(String uri, String localName,\r
+                                               String qName, Attributes attributes)\r
+                                               throws SAXException {\r
+                                       stack.addFirst(qName);\r
+                                       int mx = stack.size();\r
+                                       if (mx >= 2 && stack.get(1).equals("parts")) {\r
+                                               if ("local-name".equals(qName)) {\r
+                                                       partsLocalNameLang = attributes.getValue(\r
+                                                                       XMLConstants.XML_NS_URI, "lang");\r
+                                               }\r
+\r
+                                       } else if (mx >= 2 && stack.get(1).equals("author")) {\r
+                                               if ("name".equals(qName)) {\r
+                                                       authorNameLang = attributes.getValue(\r
+                                                                       XMLConstants.XML_NS_URI, "lang");\r
+\r
+                                               } else if ("home-page".equals(qName)) {\r
+                                                       homepageLang = attributes.getValue(\r
+                                                                       XMLConstants.XML_NS_URI, "lang");\r
+                                               }\r
+\r
+                                       } else if ("author".equals(qName)) {\r
+                                               partsAuthorInfo = null;\r
+                                               authorName = null;\r
+                                               authorNameLang = null;\r
+                                               homepageURL = null;\r
+                                               homepageLang = null;\r
+\r
+                                       } else if ("download-url".equals(qName)) {\r
+                                               downloadURL = null;\r
+\r
+                                       } else if ("parts".equals(qName)) {\r
+                                               partsLocalName = null;\r
+                                               partsLocalNameLang = null;\r
+                                               partsCategoryId = attributes.getValue("category");\r
+                                               partsName = attributes.getValue("name");\r
+                                               String strVersion = attributes.getValue("version");\r
+                                               try {\r
+                                                       if (strVersion == null || strVersion.length() == 0) {\r
+                                                               partsVersion = 0.;\r
+\r
+                                                       } else {\r
+                                                               partsVersion = Double.parseDouble(strVersion);\r
+                                                               if (partsVersion < 0) {\r
+                                                                       partsVersion = 0;\r
+                                                               }\r
+                                                       }\r
+\r
+                                               } catch (Exception ex) {\r
+                                                       logger.log(Level.INFO,\r
+                                                                       "parts-info.xml: invalid version."\r
+                                                                                       + strVersion);\r
+                                                       partsVersion = 0;\r
+                                               }\r
+                                       }\r
+\r
+                                       buf = new StringBuilder();\r
+                               }\r
+                               @Override\r
+                               public void endElement(String uri, String localName,\r
+                                               String qName) throws SAXException {\r
+\r
+                                       int mx = stack.size();\r
+\r
+                                       if (mx >= 2 && "parts".equals(stack.get(1))) {\r
+                                               if ("local-name".equals(qName)) {\r
+                                                       if (partsLocalName == null\r
+                                                                       || lang.equals(partsLocalNameLang)) {\r
+                                                               partsLocalName = buf.toString();\r
+                                                       }\r
+                                               }\r
+\r
+                                       } else if (mx >= 2 && "author".equals(stack.get(1))) {\r
+                                               if ("name".equals(qName)) {\r
+                                                       if (authorName == null\r
+                                                                       || lang.equals(authorNameLang)) {\r
+                                                               authorName = buf.toString();\r
+                                                       }\r
+\r
+                                               } else if ("home-page".equals(qName)) {\r
+                                                       if (homepageURL == null\r
+                                                                       || lang.equals(homepageLang)) {\r
+                                                               homepageURL = buf.toString();\r
+                                                       }\r
+                                               }\r
+\r
+                                       } else if ("author".equals(qName)) {\r
+                                               logger.log(Level.FINE, "parts-info: author: "\r
+                                                               + authorName + " /homepage:" + homepageURL);\r
+                                               if (authorName != null && authorName.length() > 0) {\r
+                                                       partsAuthorInfo = new PartsAuthorInfo();\r
+                                                       partsAuthorInfo.setAuthor(authorName);\r
+                                                       partsAuthorInfo.setHomePage(homepageURL);\r
+\r
+                                               } else {\r
+                                                       partsAuthorInfo = null;\r
+                                               }\r
+\r
+                                       } else if ("download-url".equals(qName)) {\r
+                                               downloadURL = buf.toString();\r
+                                               logger.log(Level.FINE, "parts-info: download-url: "\r
+                                                               + downloadURL);\r
+\r
+                                       } else if ("parts".equals(qName)) {\r
+                                               if (logger.isLoggable(Level.FINE)) {\r
+                                                       logger.log(Level.FINE,\r
+                                                                       "parts-info.xml: parts-name: " + partsName\r
+                                                                                       + " /category: " + partsCategoryId\r
+                                                                                       + " /parts-local-name: "\r
+                                                                                       + partsLocalName + " /version:"\r
+                                                                                       + partsVersion);\r
+                                               }\r
+\r
+                                               PartsManageData.PartsVersionInfo versionInfo = new PartsManageData.PartsVersionInfo();\r
+                                               versionInfo.setVersion(partsVersion);\r
+                                               versionInfo.setDownloadURL(downloadURL);\r
+\r
+                                               PartsManageData.PartsKey partsKey = new PartsManageData.PartsKey(\r
+                                                               partsName, partsCategoryId);\r
+\r
+                                               partsManageData.putPartsInfo(partsKey, partsLocalName,\r
+                                                               partsAuthorInfo, versionInfo);\r
+\r
+                                       }\r
+                                       stack.removeFirst();\r
+                               }\r
+                       });\r
+\r
+               } catch (SAXException ex) {\r
+                       IOException ex2 = new IOException("parts-info.xml read failed.");\r
+                       ex2.initCause(ex);\r
+                       throw ex2;\r
+               }\r
+\r
+               return partsManageData;\r
+       }\r
+}\r
diff --git a/src/charactermanaj/model/io/PartsInfoXMLWriter.java b/src/charactermanaj/model/io/PartsInfoXMLWriter.java
new file mode 100644 (file)
index 0000000..97c765c
--- /dev/null
@@ -0,0 +1,256 @@
+package charactermanaj.model.io;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.io.OutputStreamWriter;\r
+import java.net.URI;\r
+import java.nio.charset.Charset;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Locale;\r
+\r
+import javax.xml.XMLConstants;\r
+import javax.xml.parsers.DocumentBuilder;\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.transform.OutputKeys;\r
+import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerConfigurationException;\r
+import javax.xml.transform.TransformerException;\r
+import javax.xml.transform.TransformerFactory;\r
+import javax.xml.transform.dom.DOMSource;\r
+import javax.xml.transform.stream.StreamResult;\r
+\r
+import org.w3c.dom.Attr;\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.Element;\r
+\r
+import charactermanaj.model.PartsAuthorInfo;\r
+import charactermanaj.model.PartsManageData;\r
+import charactermanaj.model.PartsManageData.PartsKey;\r
+\r
+public class PartsInfoXMLWriter {\r
+\r
+       /**\r
+        * パーツ定義XMLファイルの名前空間\r
+        */\r
+       public static final String NS_PARTSDEF = "http://charactermanaj.sourceforge.jp/schema/charactermanaj-partsdef";\r
+\r
+       /**\r
+        * パーツ管理情報をDocBaseと同じフォルダ上のparts-info.xmlに書き出す.<br>\r
+        * XML生成中に失敗した場合は既存の管理情報は残される.<br>\r
+        * (管理情報の書き込み中にI/O例外が発生した場合は管理情報は破壊される.)<br>\r
+        * \r
+        * @param docBase\r
+        *            character.xmlの位置\r
+        * @param partsManageData\r
+        *            パーツ管理情報\r
+        * @throws IOException\r
+        *             出力に失敗した場合\r
+        */\r
+       public void savePartsManageData(URI docBase, PartsManageData partsManageData)\r
+                       throws IOException {\r
+               if (docBase == null || partsManageData == null) {\r
+                       throw new IllegalArgumentException();\r
+               }\r
+\r
+               if (!"file".equals(docBase.getScheme())) {\r
+                       throw new IOException("ファイル以外はサポートしていません: " + docBase);\r
+               }\r
+               File docBaseFile = new File(docBase);\r
+               File baseDir = docBaseFile.getParentFile();\r
+\r
+               // データからXMLを構築してストリームに出力する.\r
+               // 完全に成功したXMLのみ書き込むようにするため、一旦バッファする。\r
+               ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
+               try {\r
+                       savePartsManageData(partsManageData, bos);\r
+               } finally {\r
+                       bos.close();\r
+               }\r
+\r
+               // バッファされたXMLデータを実際のファイルに書き込む\r
+               File partsInfoXML = new File(baseDir, "parts-info.xml");\r
+               FileOutputStream os = new FileOutputStream(partsInfoXML);\r
+               try {\r
+                       os.write(bos.toByteArray());\r
+               } finally {\r
+                       os.close();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * パーツ管理情報をXMLとしてストリームに書き出す.<br>\r
+        * \r
+        * @param partsManageData\r
+        *            パーツ管理データ\r
+        * @param outstm\r
+        *            出力先ストリーム\r
+        * @throws IOException\r
+        *             出力に失敗した場合\r
+        */\r
+       public void savePartsManageData(PartsManageData partsManageData,\r
+                       OutputStream outstm) throws IOException {\r
+               if (partsManageData == null || outstm == null) {\r
+                       throw new IllegalArgumentException();\r
+               }\r
+\r
+               Document doc;\r
+               try {\r
+                       DocumentBuilderFactory factory = DocumentBuilderFactory\r
+                                       .newInstance();\r
+                       factory.setNamespaceAware(true);\r
+                       DocumentBuilder builder = factory.newDocumentBuilder();\r
+                       doc = builder.newDocument();\r
+\r
+               } catch (ParserConfigurationException ex) {\r
+                       throw new RuntimeException("JAXP Configuration Exception.", ex);\r
+               }\r
+\r
+               Locale locale = Locale.getDefault();\r
+               String lang = locale.getLanguage();\r
+\r
+               Element root = doc.createElementNS(NS_PARTSDEF, "parts-definition");\r
+\r
+               root.setAttribute("xmlns:xml", XMLConstants.XML_NS_URI);\r
+               root.setAttribute("xmlns:xsi",\r
+                               "http://www.w3.org/2001/XMLSchema-instance");\r
+               root.setAttribute("xsi:schemaLocation", NS_PARTSDEF\r
+                               + " parts-definition.xsd");\r
+               doc.appendChild(root);\r
+\r
+               // 作者情報を取得する\r
+               Collection<PartsAuthorInfo> partsAuthors = partsManageData\r
+                               .getAuthorInfos();\r
+               for (PartsAuthorInfo partsAuthorInfo : partsAuthors) {\r
+                       String author = partsAuthorInfo.getAuthor();\r
+                       if (author == null || author.length() == 0) {\r
+                               continue;\r
+                       }\r
+\r
+                       // 作者情報の登録\r
+                       Element nodeAuthor = doc.createElementNS(NS_PARTSDEF, "author");\r
+                       Element nodeAuthorName = doc.createElementNS(NS_PARTSDEF, "name");\r
+                       Attr attrLang = doc.createAttributeNS(XMLConstants.XML_NS_URI,\r
+                                       "lang");\r
+                       attrLang.setValue(lang);\r
+                       nodeAuthorName.setAttributeNodeNS(attrLang);\r
+                       nodeAuthorName.setTextContent(author);\r
+                       nodeAuthor.appendChild(nodeAuthorName);\r
+\r
+                       String homepageURL = partsAuthorInfo.getHomePage();\r
+                       if (homepageURL != null && homepageURL.length() > 0) {\r
+                               Element nodeHomepage = doc.createElementNS(NS_PARTSDEF,\r
+                                               "home-page");\r
+                               Attr attrHomepageLang = doc.createAttributeNS(\r
+                                               XMLConstants.XML_NS_URI, "lang");\r
+                               attrHomepageLang.setValue(lang);\r
+                               nodeHomepage.setAttributeNodeNS(attrHomepageLang);\r
+                               nodeHomepage.setTextContent(homepageURL);\r
+                               nodeAuthor.appendChild(nodeHomepage);\r
+                       }\r
+\r
+                       root.appendChild(nodeAuthor);\r
+\r
+                       Collection<PartsKey> partsKeys = partsManageData\r
+                                       .getPartsKeysByAuthor(author);\r
+\r
+                       // ダウンロード別にパーツキーの集約\r
+                       HashMap<String, List<PartsKey>> downloadMap = new HashMap<String, List<PartsKey>>();\r
+                       for (PartsKey partsKey : partsKeys) {\r
+                               PartsManageData.PartsVersionInfo versionInfo = partsManageData\r
+                                               .getVersionStrict(partsKey);\r
+                               String downloadURL = versionInfo.getDownloadURL();\r
+                               if (downloadURL == null) {\r
+                                       downloadURL = "";\r
+                               }\r
+                               List<PartsKey> partsKeyGrp = downloadMap.get(downloadURL);\r
+                               if (partsKeyGrp == null) {\r
+                                       partsKeyGrp = new ArrayList<PartsKey>();\r
+                                       downloadMap.put(downloadURL, partsKeyGrp);\r
+                               }\r
+                               partsKeyGrp.add(partsKey);\r
+                       }\r
+\r
+                       // ダウンロード別にパーツ情報の登録\r
+                       ArrayList<String> downloadURLs = new ArrayList<String>(\r
+                                       downloadMap.keySet());\r
+                       Collections.sort(downloadURLs);\r
+\r
+                       for (String downloadURL : downloadURLs) {\r
+                               List<PartsKey> partsKeyGrp = downloadMap.get(downloadURL);\r
+                               Collections.sort(partsKeyGrp);\r
+\r
+                               Element nodeDownload = doc.createElementNS(NS_PARTSDEF,\r
+                                               "download-url");\r
+                               nodeDownload.setTextContent(downloadURL);\r
+                               root.appendChild(nodeDownload);\r
+\r
+                               for (PartsKey partsKey : partsKeyGrp) {\r
+                                       PartsManageData.PartsVersionInfo versionInfo = partsManageData\r
+                                                       .getVersionStrict(partsKey);\r
+\r
+                                       Element nodeParts = doc.createElementNS(NS_PARTSDEF,\r
+                                                       "parts");\r
+\r
+                                       nodeParts.setAttribute("name", partsKey.getPartsName());\r
+                                       if (partsKey.getCategoryId() != null) {\r
+                                               nodeParts.setAttribute("category",\r
+                                                               partsKey.getCategoryId());\r
+                                       }\r
+                                       if (versionInfo.getVersion() > 0) {\r
+                                               nodeParts.setAttribute("version",\r
+                                                               Double.toString(versionInfo.getVersion()));\r
+                                       }\r
+\r
+                                       String localizedName = partsManageData\r
+                                                       .getLocalizedName(partsKey);\r
+                                       if (localizedName != null\r
+                                                       && localizedName.trim().length() > 0) {\r
+                                               Element nodeLocalizedName = doc.createElementNS(\r
+                                                               NS_PARTSDEF, "local-name");\r
+                                               Attr attrLocalizedNameLang = doc.createAttributeNS(\r
+                                                               XMLConstants.XML_NS_URI, "lang");\r
+                                               attrLocalizedNameLang.setValue(lang);\r
+                                               nodeLocalizedName\r
+                                                               .setAttributeNodeNS(attrLocalizedNameLang);\r
+                                               nodeLocalizedName.setTextContent(localizedName);\r
+                                               nodeParts.appendChild(nodeLocalizedName);\r
+                                       }\r
+\r
+                                       root.appendChild(nodeParts);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // output xml\r
+               TransformerFactory txFactory = TransformerFactory.newInstance();\r
+               txFactory.setAttribute("indent-number", Integer.valueOf(4));\r
+               Transformer tfmr;\r
+               try {\r
+                       tfmr = txFactory.newTransformer();\r
+               } catch (TransformerConfigurationException ex) {\r
+                       throw new RuntimeException("JAXP Configuration Failed.", ex);\r
+               }\r
+               tfmr.setOutputProperty(OutputKeys.INDENT, "yes");\r
+\r
+               // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504745\r
+               final String encoding = "UTF-8";\r
+               tfmr.setOutputProperty("encoding", encoding);\r
+               try {\r
+                       tfmr.transform(new DOMSource(doc), new StreamResult(\r
+                                       new OutputStreamWriter(outstm, Charset.forName(encoding))));\r
+\r
+               } catch (TransformerException ex) {\r
+                       IOException ex2 = new IOException("XML Convert failed.");\r
+                       ex2.initCause(ex);\r
+                       throw ex2;\r
+               }\r
+       }\r
+}\r
index bb7de1f..622174e 100644 (file)
@@ -60,7 +60,7 @@ import charactermanaj.model.PartsCategory;
 import charactermanaj.model.PartsIdentifier;\r
 import charactermanaj.model.PartsManageData;\r
 import charactermanaj.model.PartsSpec;\r
-import charactermanaj.model.io.CharacterDataPersistent;\r
+import charactermanaj.model.io.PartsInfoXMLWriter;\r
 import charactermanaj.ui.model.AbstractTableModelWithComboBoxModel;\r
 import charactermanaj.util.DesktopUtilities;\r
 import charactermanaj.util.ErrorMessageHelper;\r
@@ -671,10 +671,10 @@ public class PartsManageDialog extends JDialog {
                }\r
                \r
                // パーツ管理情報を書き込む.\r
-               CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
+               PartsInfoXMLWriter xmlWriter = new PartsInfoXMLWriter();\r
                try {\r
                        URI docBase = characterData.getDocBase();\r
-                       persist.savePartsManageData(docBase, partsManageData);\r
+                       xmlWriter.savePartsManageData(docBase, partsManageData);\r
 \r
                } catch (Exception ex) {\r
                        ErrorMessageHelper.showErrorDialog(this, ex);\r
@@ -687,6 +687,7 @@ public class PartsManageDialog extends JDialog {
 \r
        /**\r
         * パーツ管理情報が更新されたか?\r
+        * \r
         * @return 更新された場合はtrue、そうでなければfalse\r
         */\r
        public boolean isUpdated() {\r
@@ -979,8 +980,11 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
         * ホームページはAuthorに対して1つであるが、Authorが自由編集可能であるため便宜的にRowに持たせている.<br>\r
         * 結果として同じAuthorに対して同じ値を設定する必要がある.<br>\r
         * ホームページはテーブルに表示されないのでリスナーへの通知は行わない.<br>\r
-        * @param author 作者、空またはnullは何もしない.\r
-        * @param homepage ホームページ\r
+        * \r
+        * @param author\r
+        *            作者、空またはnullは何もしない.\r
+        * @param homepage\r
+        *            ホームページ\r
         */\r
        public void setHomepage(String author, String homepage) {\r
                if (author == null || author.length() == 0) {\r
@@ -1000,7 +1004,9 @@ class PartsManageTableModel extends AbstractTableModelWithComboBoxModel<PartsMan
        /**\r
         * ホームページを取得する.<br>\r
         * 該当する作者がないか、作者がnullまたは空の場合は常にnullを返す.<br>\r
-        * @param author 作者\r
+        * \r
+        * @param author\r
+        *            作者\r
         * @return ホームページ、またはnull\r
         */\r
        public String getHomepage(String author) {\r
index 4696af8..ba382a3 100644 (file)
@@ -19,8 +19,10 @@ import charactermanaj.model.PartsManageData;
 import charactermanaj.model.io.CharacterDataDefaultProvider;\r
 import charactermanaj.model.io.CharacterDataPersistent;\r
 import charactermanaj.model.io.CharacterDataPersistent.ListProfileCallback;\r
+import charactermanaj.model.io.CharacterDataPersistent.ProfileListErrorHandler;\r
 import charactermanaj.model.io.PartsDataLoader;\r
 import charactermanaj.model.io.PartsDataLoaderFactory;\r
+import charactermanaj.model.io.PartsInfoXMLReader;\r
 import charactermanaj.model.io.PartsManageDataDecorateLoader;\r
 import charactermanaj.model.io.PartsSpecDecorateLoader;\r
 import charactermanaj.model.io.RecentDataPersistent;\r
@@ -133,7 +135,13 @@ public final class ProfileListManager {
        public static MainFrame openProfile(JFrame parent) throws IOException {\r
                // キャラクタープロファイルのリストをロード\r
                CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
-               List<CharacterData> characterDatas = persist.listProfiles(CharacterDataPersistent.DEFAULT_ERROR_HANDLER);\r
+               List<CharacterData> characterDatas = persist\r
+                               .listProfiles(new ProfileListErrorHandler() {\r
+                                       public void occureException(File baseDir, Throwable ex) {\r
+                                               logger.log(Level.WARNING, "invalid profile. :"\r
+                                                               + baseDir, ex);\r
+                                       }\r
+                               });\r
 \r
                // 選択ダイアログを表示\r
                ProfileSelectorDialog selDlg = new ProfileSelectorDialog(parent, characterDatas);\r
@@ -335,8 +343,8 @@ public final class ProfileListManager {
                                                }\r
                                                public boolean occureException(File baseDir,\r
                                                                Exception ex) {\r
-                                                       CharacterDataPersistent.DEFAULT_ERROR_HANDLER\r
-                                                                       .occureException(baseDir, ex);\r
+                                                       logger.log(Level.WARNING, "invalid profile. :"\r
+                                                                       baseDir, ex);\r
                                                        // エラーでも継続する\r
                                                        return true;\r
                                                }\r
@@ -389,7 +397,7 @@ public final class ProfileListManager {
         */\r
        public static void loadCharacterData(final CharacterData characterData) throws IOException {\r
                if (characterData != null && characterData.isValid()) {\r
-                       final CharacterDataPersistent persistent = CharacterDataPersistent.getInstance();\r
+                       final PartsInfoXMLReader xmlReader = new PartsInfoXMLReader();\r
                        \r
                        PartsDataLoaderFactory loaderFactory = PartsDataLoaderFactory.getInstance();\r
                        PartsDataLoader loader = loaderFactory.createPartsLoader(characterData.getDocBase());\r
@@ -398,7 +406,9 @@ public final class ProfileListManager {
                                        = new PartsManageDataDecorateLoader(colorGroupInfoDecorater, new PartsManageDataDecorateLoader.PartsManageDataFactory() {\r
                                                public PartsManageData createPartsManageData() {\r
                                                        try {\r
-                                                               return persistent.loadPartsManageData(characterData.getDocBase());\r
+                                                               return xmlReader\r
+                                                                               .loadPartsManageData(characterData\r
+                                                                                               .getDocBase());\r
                                                        } catch (Exception ex) {\r
                                                                logger.log(Level.WARNING, "parts-info.xml loading failed.", ex);\r
                                                                return new PartsManageData();\r