1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.atlassian.theplugin.commons.cfg.xstream;
17
18 import com.atlassian.theplugin.commons.cfg.PrivateConfigurationDao;
19 import com.atlassian.theplugin.commons.cfg.PrivateServerCfgInfo;
20 import com.atlassian.theplugin.commons.cfg.ServerCfgFactoryException;
21 import com.atlassian.theplugin.commons.cfg.ServerId;
22 import com.thoughtworks.xstream.XStream;
23 import com.thoughtworks.xstream.io.xml.JDomReader;
24 import com.thoughtworks.xstream.io.xml.JDomWriter;
25 import org.jdom.Document;
26 import org.jdom.Element;
27 import org.jdom.JDOMException;
28 import org.jdom.input.SAXBuilder;
29 import org.jdom.output.Format;
30 import org.jdom.output.XMLOutputter;
31 import org.jetbrains.annotations.NotNull;
32
33 import java.io.File;
34 import java.io.FileWriter;
35 import java.io.IOException;
36
37
38
39
40
41 public class HomeDirPrivateConfigurationDao implements PrivateConfigurationDao {
42 private static final String ATLASSIAN_DIR_NAME = ".atlassian";
43 private static final String ATLASSIAN_IDE_CONNECTOR_DIR_NAME = "ide-connector";
44 private static final String ROOT_ELEMENT_NAME = "single-server-private-cfg";
45
46
47 public PrivateServerCfgInfo load(final ServerId id) throws ServerCfgFactoryException {
48 final File atlassianDir = getPrivateCfgDirectorySavePath();
49
50 if (atlassianDir.isDirectory() && atlassianDir.canRead()) {
51 final File serverCfgFile = new File(atlassianDir.getAbsolutePath(), id.getUuid().toString());
52 if (serverCfgFile.isFile() && serverCfgFile.canRead()) {
53 Document doc;
54
55 final SAXBuilder builder = new SAXBuilder(false);
56 try {
57
58 doc = builder.build(serverCfgFile.getAbsolutePath());
59 } catch (JDOMException e) {
60 throw new ServerCfgFactoryException("Cannot parse server cfg file " + e.getMessage());
61 } catch (IOException e) {
62 throw new ServerCfgFactoryException("Cannot read sever cfg file " + e.getMessage());
63 }
64
65 PrivateServerCfgInfo privateServerCfgInfo = null;
66 if (doc != null) {
67 privateServerCfgInfo = load(doc);
68 }
69 return privateServerCfgInfo;
70 } else {
71 return null;
72 }
73
74 } else {
75 throw new ServerCfgFactoryException("Cannot read private configuration stored in directory ["
76 + atlassianDir.getAbsolutePath() + "]. Directory does not exist or is not accessible");
77 }
78
79 }
80
81 static PrivateServerCfgInfo load(final Document doc) throws ServerCfgFactoryException {
82 return loadJDom(doc.getRootElement(), PrivateServerCfgInfo.class);
83 }
84
85 public void save(@NotNull final PrivateServerCfgInfo info) throws ServerCfgFactoryException {
86 Document document = createJDom(info);
87
88 try {
89
90 writeXmlFile(document.getRootElement(), new File(getPrivateCfgDirectorySavePath(),
91 info.getServerId().getUuid().toString()));
92 } catch (IOException e) {
93 final ServerCfgFactoryException ex = new ServerCfgFactoryException(e.getMessage());
94 ex.initCause(e);
95 throw ex;
96 }
97
98 }
99
100 static Document createJDom(final PrivateServerCfgInfo info) {
101 Document document = new Document(new Element(ROOT_ELEMENT_NAME));
102 saveJDom(info, document.getRootElement());
103 return document;
104 }
105
106
107
108 private File getPrivateCfgDirectorySavePath() throws ServerCfgFactoryException {
109
110 final File ideConnectorHomeDir = new File(getPrivateCfgDirectoryPath());
111 if (ideConnectorHomeDir.exists() == false) {
112 if (ideConnectorHomeDir.mkdirs() == false) {
113 throw new ServerCfgFactoryException("Cannot create directory [" + ideConnectorHomeDir.getAbsolutePath() + "]");
114 }
115 }
116
117
118 if (ideConnectorHomeDir.isDirectory() && ideConnectorHomeDir.canWrite()) {
119 return ideConnectorHomeDir;
120 }
121 throw new ServerCfgFactoryException("[" + ideConnectorHomeDir.getAbsolutePath() + "] is not writable"
122 + " or is not a directory");
123 }
124
125
126 private String getPrivateCfgDirectoryPath() {
127 return System.getProperty("user.home") + File.separator + ATLASSIAN_DIR_NAME
128 + File.separator + ATLASSIAN_IDE_CONNECTOR_DIR_NAME;
129 }
130
131
132 private void writeXmlFile(final Element element, @NotNull final File outputFile) throws IOException {
133 final FileWriter writer = new FileWriter(outputFile);
134 new XMLOutputter(Format.getPrettyFormat()).output(element, writer);
135 writer.close();
136 }
137
138 static void saveJDom(final Object object, final Element rootElement) {
139 if (object == null) {
140 throw new NullPointerException("Serialized object cannot be null");
141 }
142 final JDomWriter writer = new JDomWriter(rootElement);
143 final XStream xStream = JDomXStreamUtil.getProjectJDomXStream();
144 xStream.marshal(object, writer);
145
146
147 }
148
149 private static <T> T loadJDom(final Element rootElement, Class<T> clazz) throws ServerCfgFactoryException {
150 final int childCount = rootElement.getChildren().size();
151 if (childCount != 1) {
152 throw new ServerCfgFactoryException("Cannot travers JDom tree. Exactly one child node expected, but found ["
153 + childCount + "]");
154 }
155 final JDomReader reader = new JDomReader((Element) rootElement.getChildren().get(0));
156 final XStream xStream = JDomXStreamUtil.getProjectJDomXStream();
157 try {
158 return clazz.cast(xStream.unmarshal(reader));
159 } catch (ClassCastException e) {
160 throw new ServerCfgFactoryException("Cannot load " + clazz.getSimpleName() + " due to ClassCastException: "
161 + e.getMessage(), e);
162 } catch (Exception e) {
163 throw new ServerCfgFactoryException("Cannot load " + clazz.getSimpleName() + ": "
164 + e.getMessage(), e);
165 }
166 }
167 }