PageRenderTime 57ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/atlassian/uwc/ui/Page.java

https://bitbucket.org/appfusions/universal-wiki-converter
Java | 506 lines | 278 code | 72 blank | 156 comment | 41 complexity | 402d840d18150b6b0f3f043211997bbf MD5 | raw file
  1. package com.atlassian.uwc.ui;
  2. import java.io.File;
  3. import java.util.Date;
  4. import java.util.HashMap;
  5. import java.util.HashSet;
  6. import java.util.Set;
  7. import java.util.Vector;
  8. /**
  9. * A class representing a wiki page that is being converted to Confluence.
  10. * This holds the meta data needed to convert a Page.
  11. *
  12. * User: Rex (Rolf Staflin)
  13. * Date: 2006-94-05
  14. * Time: 15:40:25
  15. */
  16. public class Page implements Comparable {
  17. /**
  18. * File the page represents
  19. */
  20. private File file;
  21. /**
  22. * text that the page has before each conversion
  23. */
  24. private String originalText;
  25. /**
  26. * original source text. This should never be changed once
  27. * it is set. Note: This is different from originalText in that
  28. * originalText will be updated to reflect the most current
  29. * text at the beginning of each syntax conversion.
  30. */
  31. private String unchangedSource;
  32. /**
  33. * text that the page has after the conversion
  34. */
  35. private String convertedText;
  36. /**
  37. * page name. Will be used by Confluence when the page is created in Confluence.
  38. */
  39. private String name;
  40. /**
  41. * filepath to the page
  42. */
  43. private String path;
  44. /**
  45. * set of attachments associated with this page
  46. */
  47. private Set<Attachment> attachments;
  48. /**
  49. * page version, used by the UWC Page History Framework.
  50. * @see http://confluence.atlassian.com/display/CONFEXT/UWC+Page+History+Framework
  51. */
  52. private int version = 1; //the default is 1
  53. /**
  54. * set of labels associated with this page
  55. */
  56. private Set<String> labels;
  57. /**
  58. * list of page comments associated with this page
  59. * NOTE: At this time, we're only passing in the comment contents,
  60. * as all other comment parameters either (a) can't be set with
  61. * the remote api or (b) will not need to be assocated seperately (page id)
  62. */
  63. private Vector<Comment> comments; //It's a vector instead of a set to preserver order
  64. /**
  65. * username of author who updated this page. If null, the administrator running the UWC will be used
  66. */
  67. private String author;
  68. /**
  69. * timestamp when the author updated this page.
  70. */
  71. private Date timestamp;
  72. /**
  73. * map providing information about which version is the latest for a given title.
  74. * There should only be data in this object if pages have been sorted by history in the ConverterEngine
  75. */
  76. private static HashMap<String, Integer> latestVersions = new HashMap<String, Integer>();
  77. /**
  78. * Optionally associate the page with a spacekey. The ConverterEngine will use this instead of the spacekey setting.
  79. */
  80. private String spacekey;
  81. /**
  82. * keep needed space data here so the ConverterEngine can create the space, if necessary
  83. * The key is the spacekey. The value is an array with name and description data in the 0th and 1st indexes,
  84. * respectively. The name and description data will only be used if the spacekey is not already in use, and
  85. * therefore a space needs to be created.
  86. */
  87. private static HashMap<String,String[]> spaces = new HashMap<String, String[]>(); //spacekey -> [name, description]
  88. private boolean isBlog = false;
  89. private boolean isPersonalSpace = false;
  90. private String personalSpaceUsername = null;
  91. /**
  92. * If the page history framework is using the load-as-ancestors properties, then we load the ancestor versions of
  93. * the page into this object. Useful for interacting more easily with existing hierarchies.
  94. */
  95. private Vector<VersionPage> ancestors;
  96. /**
  97. * confluence entity id. useful for updating blogs.
  98. */
  99. private String id;
  100. /**
  101. * set by the engine, used by the compareTo method
  102. */
  103. private boolean sortWithTimestamp = false;
  104. /**
  105. * Basic constructor. Creates a page with an empty path.
  106. * @param file The file to be converted.
  107. */
  108. public Page(File file) {
  109. init(file, "");
  110. }
  111. /**
  112. * Basic constructor.
  113. * @param file The file to be converted.
  114. * @param path A path used to construct a page hierarchy for
  115. * some wikis.
  116. */
  117. public Page(File file, String path) {
  118. init(file, path);
  119. }
  120. /**
  121. * initializes the page
  122. * @param file
  123. * @param path
  124. */
  125. private void init(File file, String path) {
  126. this.file = file;
  127. attachments = new HashSet<Attachment>();
  128. labels = new HashSet<String>();
  129. comments = new Vector<Comment>();
  130. setPath(path);
  131. }
  132. /**
  133. * used when sorting pages.
  134. * Takes into account page name and page version
  135. * @see java.lang.Comparable#compareTo(java.lang.Object)
  136. */
  137. public int compareTo(Object o) {
  138. Page b = (Page) o;
  139. int versionA = this.version;
  140. int versionB = b.getVersion();
  141. String nameA = this.name;
  142. String nameB = b.getName();
  143. //make sure there's a default value so we don't get NPE
  144. if (nameA == null) nameA = "";
  145. if (nameB == null) nameB = "";
  146. //order by name - if name is the same, in order by version
  147. int compareValue = (nameA.compareTo(nameB));
  148. if (compareValue == 0) {
  149. if (!sortWithTimestamp) compareValue = versionA - versionB;
  150. }
  151. //if these are the same, double check file path in case the filename is the same
  152. if (compareValue == 0) {
  153. String pathA = this.path;
  154. String pathB = b.getPath();
  155. compareValue = pathA.compareTo(pathB);
  156. }
  157. //NOTE: If we return 0, only one of these objects will win in a Set that is sorted with this method.
  158. return compareValue;
  159. }
  160. /**
  161. * Adds a single attachment to the page. If the attachment was already
  162. * added (e.g., an image that appears several times on the page) it is not added again.
  163. * @param newAttachment The file to be attached to the page. It must not be null.
  164. */
  165. public void addAttachment(File newAttachment) {
  166. assert newAttachment != null;
  167. attachments.add(new Attachment(newAttachment));
  168. }
  169. public void addAttachment(File attachment, String name) {
  170. attachments.add(new Attachment(attachment, name));
  171. }
  172. public void addAttachment(Attachment attachment) {
  173. attachments.add(attachment);
  174. }
  175. /* Getters and Setters */
  176. public File getFile() {
  177. return file;
  178. }
  179. public String getOriginalText() {
  180. return originalText;
  181. }
  182. public void setOriginalText(String originalText) {
  183. this.originalText = originalText;
  184. }
  185. public String getUnchangedSource() {
  186. return unchangedSource;
  187. }
  188. /**
  189. * sets the unchangedSource field. Cannot be set more than once.
  190. * @throws IllegalStateException if the source has already been set.
  191. */
  192. public void setUnchangedSource(String unchangedSource) {
  193. if (this.unchangedSource != null)
  194. throw new IllegalStateException("Source Text has already been set. It may not be changed further.");
  195. this.unchangedSource = unchangedSource;
  196. }
  197. public String getName() {
  198. return name;
  199. }
  200. public void setName(String name) {
  201. this.name = name;
  202. }
  203. /**
  204. * Returns the relative path of the page. This path is constructed by ConverterEngine.recurse().
  205. * Top-level (root) pages have an empty path, while other pages have paths with the elements
  206. * separated by <code>File.separator</code>, e.g. "/path/to/the/page.txt" on unix systems and
  207. * "\path\to\the\page.txt" on Windows systems.
  208. *
  209. * @return The path of the page.
  210. */
  211. public String getPath() {
  212. return path;
  213. }
  214. public void setPath(String path) {
  215. this.path = path;
  216. }
  217. public String getConvertedText() {
  218. return convertedText;
  219. }
  220. public void setConvertedText(String convertedText) {
  221. this.convertedText = convertedText;
  222. }
  223. public Set<File> getAttachments() {
  224. HashSet<File> justFiles = new HashSet<File>();
  225. for (Attachment att : this.attachments) {
  226. justFiles.add(att.getFile());
  227. }
  228. return justFiles;
  229. }
  230. public void setAttachments(Set<File> attachments) {
  231. assert attachments != null;
  232. this.attachments.clear();
  233. for (File file : attachments) {
  234. this.attachments.add(new Attachment(file));
  235. }
  236. }
  237. public Set<Attachment> getAllAttachmentData() {
  238. return this.attachments;
  239. }
  240. public void setVersion(int version) {
  241. //save latest version data
  242. if (getLatestVersion(getName()) <= version) {
  243. latestVersions.put(getName(), version);
  244. }
  245. this.version = version;
  246. }
  247. public int getVersion() {
  248. return this.version;
  249. }
  250. /**
  251. * @return map of title -> latest version data.
  252. */
  253. public static HashMap<String, Integer> getLatestVersions() {
  254. return latestVersions;
  255. }
  256. /**
  257. * Latest version data is noted when setVersion is called based on the name the object has
  258. * when setVersion is called.
  259. * @param name page name this version is associated with
  260. * @return latest version for title or 1 if no version set yet
  261. */
  262. public static int getLatestVersion(String name) {
  263. Integer latest = getLatestVersions().get(name);
  264. if (latest == null) return 1;
  265. return latest;
  266. }
  267. public int getLatestVersion() {
  268. return getLatestVersion(getName());
  269. }
  270. public Set<String> getLabels() {
  271. return labels;
  272. }
  273. public void setLabels(Set<String> labels) {
  274. this.labels = labels;
  275. }
  276. /**
  277. * @return set of labels as a comma delimited list. null if
  278. * labels is null or empty
  279. */
  280. public String getLabelsAsString() {
  281. if (this.labels == null) return null;
  282. if (this.labels.isEmpty()) return null;
  283. boolean first = true;
  284. String labelString = "";
  285. for (String label : this.labels) {
  286. if (first) first = false;
  287. else labelString += ", ";
  288. labelString += label;
  289. }
  290. return labelString;
  291. }
  292. /**
  293. * adds the given label to the set of labels associated with this page,
  294. * removes disallowed confluence label chars,
  295. * and toLowerCases the label to: (a) avoid remote api errors and
  296. * (b) better represent what the results of uploading a given label to Confluence will be.
  297. * If you don't want the labels to be processed, use the setLabels method instead.
  298. * @param label
  299. */
  300. public void addLabel(String label) {
  301. label = label.trim();
  302. label = label.replaceAll("[ !#&()*,.:;<>?@\\[\\]\\^]", ""); //remove disallowed confluence tag chars
  303. label = label.toLowerCase();
  304. this.labels.add(label);
  305. }
  306. public Vector<String> getComments() {
  307. Vector<String> commentStrings = new Vector<String>();
  308. for (Comment comment : this.comments) {
  309. commentStrings.add(comment.text);
  310. }
  311. return commentStrings;
  312. }
  313. public Vector<Comment> getAllCommentData() {
  314. return this.comments;
  315. }
  316. public void setComments(Vector <String> comments) {
  317. for (String comment : comments) {
  318. this.comments.add(new Comment(comment));
  319. }
  320. }
  321. public void addComment(String comment) {
  322. this.comments.add(new Comment(comment));
  323. }
  324. public void addComment(Comment comment) {
  325. this.comments.add(comment);
  326. }
  327. public void addComment(String comment, String creator, String date) {
  328. this.comments.add(new Comment(comment, creator, date));
  329. }
  330. public boolean hasComments() {
  331. return !this.comments.isEmpty();
  332. }
  333. public String getAuthor() {
  334. return author;
  335. }
  336. public void setAuthor(String author) {
  337. this.author = author;
  338. }
  339. public Date getTimestamp() {
  340. return timestamp;
  341. }
  342. public void setTimestamp(Date timestamp) {
  343. this.timestamp = timestamp;
  344. }
  345. /* Space methods */
  346. public String getSpacekey() {
  347. return spacekey;
  348. }
  349. public void setSpacekey(String key) {
  350. this.spacekey = key;
  351. }
  352. /**
  353. * sets the spacekey for this page, and also assigns name and description data
  354. * to a map so that if the space needs to be created, we have that information.
  355. * @param key
  356. * @param name
  357. * @param desc
  358. */
  359. public void setSpace(String key, String name, String desc) {
  360. setSpacekey(key);
  361. String[] newdata = {name, desc};
  362. this.spaces.put(key, newdata);
  363. }
  364. /**
  365. * gets the space data that's been saved for a particular spacekey, or null if no data exists for that key
  366. * @param key
  367. * @return array. 0th index is the name of the space, 1st index is the description
  368. */
  369. public String[] getSpaceData(String key) {
  370. if (spaces.containsKey(key)) return spaces.get(key);
  371. return null;
  372. }
  373. /**
  374. * true if the spaces data map has an entry for the given key
  375. * @param key
  376. * @return
  377. */
  378. public boolean hasSpace(String key) {
  379. return spaces.containsKey(key);
  380. }
  381. public boolean isBlog() {
  382. return isBlog;
  383. }
  384. public void setIsBlog(boolean isBlog) {
  385. this.isBlog = isBlog;
  386. }
  387. public boolean isPersonalSpace() {
  388. return isPersonalSpace;
  389. }
  390. public void setIsPersonalSpace(boolean isPersonalSpace) {
  391. this.isPersonalSpace = isPersonalSpace;
  392. }
  393. public String getPersonalSpaceUsername() {
  394. return this.personalSpaceUsername;
  395. }
  396. public void setPersonalSpaceUsername(String username) {
  397. this.personalSpaceUsername = username;
  398. }
  399. public void addAncestor(VersionPage ancestor) {
  400. getAncestors().add(ancestor);
  401. }
  402. public Vector<VersionPage> getAncestors() {
  403. if (this.ancestors == null)
  404. this.ancestors = new Vector<VersionPage>();
  405. return this.ancestors;
  406. }
  407. public void setParent(Page page) {
  408. throw new IllegalStateException("Use VersionPage if you wish to set the parent.");
  409. }
  410. public Page getParent() {
  411. return null;
  412. }
  413. public boolean sameTimestampAndContent(Page page) {
  414. boolean content = (this.getConvertedText() != null
  415. && this.getConvertedText().equals(page.getConvertedText()));
  416. boolean timeisnull = (this.getTimestamp() == null && page.getTimestamp() == null);
  417. boolean time = (this.getTimestamp() != null
  418. && page.getTimestamp() != null
  419. && this.getTimestamp().getTime() == page.getTimestamp().getTime());
  420. return content && (timeisnull || time);
  421. }
  422. public String getId() {
  423. return id;
  424. }
  425. public void setId(String id) {
  426. this.id = id;
  427. }
  428. public boolean isSortWithTimestamp() {
  429. return sortWithTimestamp;
  430. }
  431. public void setSortWithTimestamp(boolean sortWithTimestamp) {
  432. this.sortWithTimestamp = sortWithTimestamp;
  433. }
  434. }