Moxkiriyaプロジェクト事前開発用の作業部屋
修订版 | 2989314ec31f1e439e4893116990e4898705d260 (tree) |
---|---|
时间 | 2018-09-29 16:41:32 |
作者 | Harold_Andoh <andolloyd@gmai...> |
Commiter | Harold_Andoh |
[Moxkiriya7]
@@ -12,11 +12,13 @@ import java.io.File; | ||
12 | 12 | import java.io.FileInputStream; |
13 | 13 | import java.io.InputStream; |
14 | 14 | import java.io.StringReader; |
15 | +import java.net.URLConnection; | |
15 | 16 | import java.util.ArrayList; |
16 | 17 | import java.util.Calendar; |
17 | 18 | import java.util.regex.Pattern; |
18 | 19 | |
19 | 20 | import javax.activation.FileTypeMap; |
21 | +import javax.activation.MimetypesFileTypeMap; | |
20 | 22 | import javax.jcr.Node; |
21 | 23 | import javax.jcr.PathNotFoundException; |
22 | 24 | import javax.jcr.Property; |
@@ -312,7 +314,7 @@ public class PageData { | ||
312 | 314 | count++; |
313 | 315 | if(charArrayContent[count] == ']') { |
314 | 316 | if(content.startsWith("]]", count) == true) { |
315 | - int endCount = count - 1; | |
317 | + int endCount = count; | |
316 | 318 | |
317 | 319 | String category = content.substring(startCount, endCount); |
318 | 320 | categories.add(category); |
@@ -432,9 +434,7 @@ public class PageData { | ||
432 | 434 | */ |
433 | 435 | public void setInputStream(File file) throws Exception { |
434 | 436 | inputStream_ = new FileInputStream(file); |
435 | - | |
436 | - FileTypeMap filetypeMap = FileTypeMap.getDefaultFileTypeMap(); | |
437 | - mimeType_ = filetypeMap.getContentType(file); | |
437 | + mimeType_ = URLConnection.guessContentTypeFromName(file.getAbsolutePath()); | |
438 | 438 | |
439 | 439 | lastModified_ = Calendar.getInstance(); |
440 | 440 | lastModified_.setTimeInMillis(file.lastModified()); |
@@ -50,7 +50,7 @@ public class SettingManager { | ||
50 | 50 | private static final String MOXKIRIYA_USER_DIR = "_moxkiriya"; |
51 | 51 | |
52 | 52 | /** 設定ファイル名 */ |
53 | - private static final String INI_FILENAME = "_moxkiriya.ini"; | |
53 | + private static final String CONFIG_FILENAME = "_moxkiriya.config"; | |
54 | 54 | |
55 | 55 | /** fixedstylesheetファイル名 */ |
56 | 56 | public static final String FIXED_STYLESHEET_FILENAME = "fixedstylesheet.css"; |
@@ -114,7 +114,7 @@ public class SettingManager { | ||
114 | 114 | private void loadSettingFiles(String path) { |
115 | 115 | try { |
116 | 116 | if (path != null) { |
117 | - File inifile = new File(path + "\\" + INI_FILENAME); | |
117 | + File inifile = new File(path + "\\" + CONFIG_FILENAME); | |
118 | 118 | if (inifile.exists() != true) { |
119 | 119 | /* |
120 | 120 | * ファイルが存在しなかった場合、ファイルを新規作成 |
@@ -191,7 +191,7 @@ public class SettingManager { | ||
191 | 191 | |
192 | 192 | try { |
193 | 193 | String path = get(SETTINGSKEY_MOXKIRIYA_USER_DIR); |
194 | - File inifile = new File(path + "\\" + INI_FILENAME); | |
194 | + File inifile = new File(path + "\\" + CONFIG_FILENAME); | |
195 | 195 | BufferedWriter writer = FileIO.bufferedWriter(inifile); |
196 | 196 | |
197 | 197 | writer.write(stringBuf.toString()); |
@@ -10,6 +10,7 @@ import java.util.ArrayList; | ||
10 | 10 | import java.util.HashMap; |
11 | 11 | import java.util.ResourceBundle; |
12 | 12 | |
13 | +import javax.jcr.Node; | |
13 | 14 | import javax.jcr.Property; |
14 | 15 | import javax.jcr.Value; |
15 | 16 |
@@ -29,6 +30,12 @@ public class WikiEngine { | ||
29 | 30 | /** jcr_uuid 独自属性 */ |
30 | 31 | public static final String ATTRIBUTE_JCR_UUID = "data-jcr_uuid"; |
31 | 32 | |
33 | + /** namespace "Cagegory" */ | |
34 | + public static final String NAMESPACE_CATEGORY = WikiRepository.PROPERTY_CATEGORY; | |
35 | + | |
36 | + /** namespace "File" */ | |
37 | + public static final String NAMESPACE_FILE = WikiRepository.PROPERTY_FILE; | |
38 | + | |
32 | 39 | /** Wiki Repository. */ |
33 | 40 | private WikiRepository wikiRepository_; |
34 | 41 |
@@ -91,46 +98,6 @@ public class WikiEngine { | ||
91 | 98 | public HashMap<String, PageData> getPageDataMap() { |
92 | 99 | return pageDataMap_; |
93 | 100 | } |
94 | - | |
95 | - /** | |
96 | - * Execute query node by namespace. | |
97 | - * @param namespace | |
98 | - * @return HashMap<String, PageData> | |
99 | - * @throws Exception | |
100 | - */ | |
101 | - public HashMap<String, PageData> queryPageNamespace(String namespace) throws Exception { | |
102 | - return wikiRepository_.queryPageNamespace(namespace); | |
103 | - } | |
104 | - | |
105 | - /** | |
106 | - * Execute query node by UUID. | |
107 | - * @param uuid | |
108 | - * @return HashMap<String, PageData> | |
109 | - * @throws Exception | |
110 | - */ | |
111 | - public HashMap<String, PageData> queryPageUUID(String uuid) throws Exception { | |
112 | - return wikiRepository_.queryPageUUID(uuid); | |
113 | - } | |
114 | - | |
115 | - /** | |
116 | - * Execute query node by pageTitle. | |
117 | - * @param pageTitle | |
118 | - * @return HashMap<String, PageData> | |
119 | - * @throws Exception | |
120 | - */ | |
121 | - public HashMap<String, PageData> queryPageTitle(String pageTitle) throws Exception { | |
122 | - return wikiRepository_.queryPageTitle(pageTitle); | |
123 | - } | |
124 | - | |
125 | - /** | |
126 | - * Execute query full text search. | |
127 | - * @param searchKey | |
128 | - * @return HashMap<String, PageData> | |
129 | - * @throws Exception | |
130 | - */ | |
131 | - public HashMap<String, PageData> queryPageFullTextSearch(String searchKey) throws Exception { | |
132 | - return wikiRepository_.queryPageFullTextSearch(searchKey); | |
133 | - } | |
134 | 101 | |
135 | 102 | /** |
136 | 103 | * NamespaceList getter. |
@@ -212,7 +179,9 @@ public class WikiEngine { | ||
212 | 179 | bodyBlockParser.parsePageTitle(currentPageData.getTitle()); |
213 | 180 | BufferedReader buffreader = FileIO.bufferedReader(new StringReader(currentPageData.getContent())); |
214 | 181 | |
215 | - bodyHtml = bodyBlockParser.parse(buffreader); | |
182 | + bodyHtml = bodyBlockParser.parse(buffreader) | |
183 | + + buildCategoryList(currentPageData); | |
184 | + | |
216 | 185 | buffreader.close(); |
217 | 186 | } |
218 | 187 | } |
@@ -321,14 +290,99 @@ public class WikiEngine { | ||
321 | 290 | return stringBuf.toString(); |
322 | 291 | } |
323 | 292 | |
293 | + private String buildCategoryList(PageData pageData) throws Exception { | |
294 | + StringBuffer buf = new StringBuffer(""); | |
295 | + ArrayList<String> categoryies = pageData.getCategories(); | |
296 | + | |
297 | + for(String category: categoryies) { | |
298 | + if(category.isEmpty() != true) { | |
299 | + HashMap<String, PageData> categoryPageMap = queryPageTitle(category, NAMESPACE_CATEGORY); | |
300 | + | |
301 | + if(categoryPageMap.size() == 1) { | |
302 | + PageData categoryPage = categoryPageMap.values().iterator().next(); | |
303 | + Node node = categoryPage.getNode(); | |
304 | + | |
305 | + buf.append("<a href=" + "\"" + category + "\" "); | |
306 | + buf.append(ATTRIBUTE_JCR_UUID + "=\""); | |
307 | + buf.append(node.getProperty(Property.JCR_UUID).getString()); | |
308 | + buf.append("\">"); | |
309 | + buf.append(category); | |
310 | + buf.append("</a> "); | |
311 | + } | |
312 | + } | |
313 | + } | |
314 | + | |
315 | + String startElem = ""; | |
316 | + String endElem = ""; | |
317 | + | |
318 | + if(buf.length() > 0) { | |
319 | + startElem = "<div class=\"categorylist\"> Categories: \n"; | |
320 | + endElem = "</div>"; | |
321 | + } | |
322 | + | |
323 | + return startElem + buf.toString() + endElem; | |
324 | + } | |
325 | + | |
326 | + | |
327 | + /** | |
328 | + * Execute query node by namespace. | |
329 | + * @param namespace | |
330 | + * @return HashMap<String, PageData> | |
331 | + * @throws Exception | |
332 | + */ | |
333 | + public HashMap<String, PageData> queryPageNamespace(String namespace) throws Exception { | |
334 | + return wikiRepository_.queryPageNamespace(namespace); | |
335 | + } | |
336 | + | |
324 | 337 | /** |
325 | - * Execute full text search. | |
326 | - * @param key | |
327 | - * @return String | |
338 | + * Execute query node by UUID. | |
339 | + * @param uuid | |
340 | + * @return HashMap<String, PageData> | |
341 | + * @throws Exception | |
342 | + */ | |
343 | + public HashMap<String, PageData> queryPageUUID(String uuid) throws Exception { | |
344 | + return wikiRepository_.queryPageUUID(uuid); | |
345 | + } | |
346 | + | |
347 | + /** | |
348 | + * Execute query node by pageTitle. | |
349 | + * @param pageTitle | |
350 | + * @param namespace | |
351 | + * @return HashMap<String, PageData> | |
352 | + * @throws Exception | |
353 | + */ | |
354 | + public HashMap<String, PageData> queryPageTitle(String pageTitle, String namespace) throws Exception { | |
355 | + return wikiRepository_.queryPageTitle(pageTitle, namespace); | |
356 | + } | |
357 | + | |
358 | + /** | |
359 | + * Execute query node by pageTitle. | |
360 | + * @param pageTitle | |
361 | + * @return HashMap<String, PageData> | |
362 | + * @throws Exception | |
363 | + */ | |
364 | + public HashMap<String, PageData> queryPageTitle(String pageTitle) throws Exception { | |
365 | + return wikiRepository_.queryPageTitle(pageTitle); | |
366 | + } | |
367 | + | |
368 | + /** | |
369 | + * Execute query full text search. | |
370 | + * @param searchKey | |
371 | + * @return HashMap<String, PageData> | |
372 | + * @throws Exception | |
373 | + */ | |
374 | + public HashMap<String, PageData> queryPageFullTextSearch(String searchKey) throws Exception { | |
375 | + return wikiRepository_.queryPageFullTextSearch(searchKey); | |
376 | + } | |
377 | + | |
378 | + /** | |
379 | + * Test namespace is contains namespaceList. | |
380 | + * @param namespace | |
381 | + * @return boolean | |
328 | 382 | * @throws Exception |
329 | 383 | */ |
330 | - public HashMap<String, PageData> fullTextSearch(String key) throws Exception { | |
331 | - return wikiRepository_.queryPageFullTextSearch(key); | |
384 | + public boolean isContainsNamespaceList(String namespace) throws Exception { | |
385 | + return wikiRepository_.isContainsNamespaceList(namespace); | |
332 | 386 | } |
333 | 387 | |
334 | 388 | /** |
@@ -101,7 +101,7 @@ | ||
101 | 101 | <Button fx:id="buttonDeletePages" mnemonicParsing="false" onAction="#onActionButtonDeletePages" prefHeight="30.0" text="%key.Button.Delete.Pages" AnchorPane.bottomAnchor="15.0" AnchorPane.leftAnchor="150.0" /> |
102 | 102 | </children> |
103 | 103 | </AnchorPane> |
104 | - <AnchorPane id="EditAnchorPane" fx:id="AnchorPaneEdit" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="450.0" prefWidth="590.0" visible="true" AnchorPane.bottomAnchor="70.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="75.0"> | |
104 | + <AnchorPane id="EditAnchorPane" fx:id="AnchorPaneEdit" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="450.0" prefWidth="590.0" visible="false" AnchorPane.bottomAnchor="70.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="75.0"> | |
105 | 105 | <children> |
106 | 106 | <Label prefHeight="30.0" text="%key.Edit.Label.Title" AnchorPane.leftAnchor="150.0" AnchorPane.topAnchor="15.0" /> |
107 | 107 | <TextField fx:id="textFieldTitle" prefHeight="30.0" prefWidth="380.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="9.0" AnchorPane.topAnchor="45.0" /> |
@@ -111,7 +111,7 @@ | ||
111 | 111 | <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#onActionButtonCancel" prefWidth="90.0" text="%key.Button.Cancel" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="10.0" /> |
112 | 112 | <TextField fx:id="textFieldAttachFile" disable="true" prefHeight="30.0" prefWidth="716.0" promptText="%key.Edit.TextField.InputPathname" AnchorPane.bottomAnchor="37.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="108.0" /> |
113 | 113 | <Label disable="true" prefHeight="30.0" prefWidth="166.0" text="%key.Edit.Label.AttachFile" AnchorPane.bottomAnchor="65.0" AnchorPane.leftAnchor="150.0" /> |
114 | - <Button disable="true" mnemonicParsing="false" prefHeight="30.0" prefWidth="45.0" text="..." AnchorPane.bottomAnchor="35.0" AnchorPane.rightAnchor="55.0" /> | |
114 | + <Button fx:id="buttonChoiceFile" disable="true" mnemonicParsing="false" onAction="#onActionButtonChoiceFile" prefHeight="30.0" prefWidth="45.0" text="..." AnchorPane.bottomAnchor="35.0" AnchorPane.rightAnchor="55.0" /> | |
115 | 115 | </children> |
116 | 116 | </AnchorPane> |
117 | 117 | </children> |
@@ -110,6 +110,7 @@ public class WikiMainWindowController implements Initializable { | ||
110 | 110 | @FXML private TextField textFieldTitle; |
111 | 111 | @FXML private TextArea textAreaContents; |
112 | 112 | @FXML private TextField textFieldAttachFile; |
113 | + @FXML private Button buttonChoiceFile; | |
113 | 114 | |
114 | 115 | /* |
115 | 116 | * AnchorPaneContentList controls. |
@@ -285,7 +286,7 @@ public class WikiMainWindowController implements Initializable { | ||
285 | 286 | String key = webViewMenuAnchorPaneTextFieldSearchWiki.getText(); |
286 | 287 | |
287 | 288 | if(key.isEmpty() != true) { |
288 | - HashMap<String, PageData> map = wikiEngine_.fullTextSearch(key); | |
289 | + HashMap<String, PageData> map = wikiEngine_.queryPageFullTextSearch(key); | |
289 | 290 | |
290 | 291 | wikiEngine_.setPageDataMap(map); |
291 | 292 | loadWikiContent(); |
@@ -414,25 +415,6 @@ public class WikiMainWindowController implements Initializable { | ||
414 | 415 | } |
415 | 416 | |
416 | 417 | @FXML |
417 | - public void onMouseClickedHyperlinkEditAttachFiles() { | |
418 | - try { | |
419 | - PageData pageData = getSelectingPageData(); | |
420 | - | |
421 | - if(pageData != null) { | |
422 | - FileChooser fileChooser = new FileChooser(); | |
423 | - fileChooser.setTitle("Select " + pageData.getTitle()); | |
424 | - File file = fileChooser.showOpenDialog(primaryStage_); | |
425 | - | |
426 | - if(file != null) { | |
427 | - textFieldAttachFile.setText(file.getPath()); | |
428 | - } | |
429 | - } | |
430 | - } catch (Exception e) { | |
431 | - e.printStackTrace(); | |
432 | - } | |
433 | - } | |
434 | - | |
435 | - @FXML | |
436 | 418 | public void onActionButtonDeletePages(ActionEvent event) { |
437 | 419 | try { |
438 | 420 | ObservableList<PageData> pageDataList = tableViewContentList.getItems(); |
@@ -463,6 +445,21 @@ public class WikiMainWindowController implements Initializable { | ||
463 | 445 | } |
464 | 446 | |
465 | 447 | @FXML |
448 | + public void onActionButtonChoiceFile(ActionEvent event) { | |
449 | + try { | |
450 | + FileChooser fileChooser = new FileChooser(); | |
451 | + fileChooser.setTitle("Select " + textFieldTitle.getText()); | |
452 | + File file = fileChooser.showOpenDialog(primaryStage_); | |
453 | + | |
454 | + if(file != null) { | |
455 | + textFieldAttachFile.setText(file.getPath()); | |
456 | + } | |
457 | + } catch (Exception e) { | |
458 | + e.printStackTrace(); | |
459 | + } | |
460 | + } | |
461 | + | |
462 | + @FXML | |
466 | 463 | public void onActionButtonSave(ActionEvent event) { |
467 | 464 | try { |
468 | 465 | String title = textFieldTitle.getText(); |
@@ -479,12 +476,19 @@ public class WikiMainWindowController implements Initializable { | ||
479 | 476 | PageData pageData = (PageData)AnchorPaneEdit.getUserData(); |
480 | 477 | |
481 | 478 | if(editMode_ == EditMode.NEW) { |
482 | - pageData = new PageData(); | |
483 | - pageData.setNamespace(WikiRepository.PROPERTY_MAIN); | |
479 | + if(pageData == null) { | |
480 | + pageData = new PageData(); | |
481 | + pageData.setNamespace(WikiRepository.PROPERTY_MAIN); | |
482 | + } | |
484 | 483 | } |
485 | 484 | |
486 | 485 | pageData.setTitle(title); |
487 | 486 | pageData.setContent(textAreaContents.getText()); |
487 | + | |
488 | + String filename = textFieldAttachFile.getText(); | |
489 | + if(filename.isEmpty() != true) { | |
490 | + pageData.setFileData(new File(filename)); | |
491 | + } | |
488 | 492 | pageData = wikiEngine_.checkin(pageData); |
489 | 493 | editMode_ = EditMode.NONE; |
490 | 494 |
@@ -550,7 +554,8 @@ public class WikiMainWindowController implements Initializable { | ||
550 | 554 | */ |
551 | 555 | public void buildEditView(EditMode editMode, String title) { |
552 | 556 | try { |
553 | - String content = ""; | |
557 | + String content = ""; | |
558 | + String namespace = ""; | |
554 | 559 | |
555 | 560 | editMode_ = editMode; |
556 | 561 |
@@ -560,11 +565,45 @@ public class WikiMainWindowController implements Initializable { | ||
560 | 565 | |
561 | 566 | AnchorPaneEdit.setUserData(pageData); |
562 | 567 | wikiEngine_.checkout(); |
563 | - title = pageData.getTitle(); | |
564 | - content = pageData.getContent(); | |
568 | + title = pageData.getTitle(); | |
569 | + content = pageData.getContent(); | |
570 | + namespace = pageData.getNamespace(); | |
565 | 571 | } |
566 | 572 | else { |
567 | 573 | AnchorPaneEdit.setUserData(null); |
574 | + | |
575 | + if(editMode_ == EditMode.NEW) { | |
576 | + if(title.isEmpty() != true) { | |
577 | + PageData pageData = new PageData(); | |
578 | + String pageTitle = title; | |
579 | + | |
580 | + namespace = title.substring(0, title.indexOf(":")); | |
581 | + | |
582 | + pageData.setNamespace(WikiRepository.PROPERTY_MAIN); | |
583 | + | |
584 | + if(namespace.isEmpty() != true) { | |
585 | + pageTitle = title.substring(namespace.length() + ":".length(), title.length()); | |
586 | + if(wikiEngine_.isContainsNamespaceList(namespace) == true) { | |
587 | + pageData.setNamespace(namespace); | |
588 | + } | |
589 | + } | |
590 | + | |
591 | + pageData.setTitle(pageTitle); | |
592 | + AnchorPaneEdit.setUserData(pageData); | |
593 | + | |
594 | + title = pageData.getTitle(); | |
595 | + namespace = pageData.getNamespace(); | |
596 | + } | |
597 | + } | |
598 | + } | |
599 | + | |
600 | + if(namespace.equals(WikiEngine.NAMESPACE_FILE) == true) { | |
601 | + textFieldAttachFile.setDisable(false); | |
602 | + buttonChoiceFile.setDisable(false); | |
603 | + } | |
604 | + else { | |
605 | + textFieldAttachFile.setDisable(true); | |
606 | + buttonChoiceFile.setDisable(true); | |
568 | 607 | } |
569 | 608 | |
570 | 609 | /* |
@@ -572,6 +611,7 @@ public class WikiMainWindowController implements Initializable { | ||
572 | 611 | */ |
573 | 612 | textFieldTitle.setText(title); |
574 | 613 | textAreaContents.setText(content); |
614 | + textFieldAttachFile.setText(""); | |
575 | 615 | |
576 | 616 | menuItemNew.setDisable(true); |
577 | 617 |
@@ -616,8 +656,10 @@ public class WikiMainWindowController implements Initializable { | ||
616 | 656 | * @throws Exception |
617 | 657 | */ |
618 | 658 | private void jumpToSectionLink(EventTarget target) throws Exception { |
619 | - String targetString = target.toString(); | |
620 | - String sectionName = URLDecoder.decode(targetString.substring(targetString.indexOf("#") + "#".length()), "UTF-8"); | |
659 | + HTMLAnchorElement anchor = (HTMLAnchorElement)target; | |
660 | + String href = anchor.getAttribute("href"); | |
661 | + String pageTitle = URLDecoder.decode(href, "UTF-8"); | |
662 | + String sectionName = pageTitle.substring(pageTitle.indexOf("#") + "#".length()); | |
621 | 663 | webView.getEngine().executeScript("scrollTo('" + sectionName + "')"); |
622 | 664 | } |
623 | 665 |
@@ -708,8 +750,9 @@ public class WikiMainWindowController implements Initializable { | ||
708 | 750 | @Override |
709 | 751 | public void handleEvent(org.w3c.dom.events.Event event) { |
710 | 752 | try { |
711 | - MouseEvent mouseEvent = (MouseEvent)event; | |
712 | - EventTarget target = mouseEvent.getCurrentTarget(); | |
753 | + MouseEvent mouseEvent = (MouseEvent)event; | |
754 | + EventTarget target = mouseEvent.getCurrentTarget(); | |
755 | + | |
713 | 756 | if(isExternalLink(target) == true) { |
714 | 757 | /* |
715 | 758 | * WebEngineのデフォルトの動作(リンク先ページをロード)をキャンセル |
@@ -737,16 +780,18 @@ public class WikiMainWindowController implements Initializable { | ||
737 | 780 | { add("https://"); } |
738 | 781 | { add("file://"); } |
739 | 782 | }; |
740 | - | |
741 | - boolean isExternal = false; | |
742 | - | |
783 | + | |
784 | + HTMLAnchorElement aElem = (HTMLAnchorElement)target; | |
785 | + String href = aElem.getAttribute("href"); | |
786 | + boolean isExternal = false; | |
787 | + | |
743 | 788 | for(String scheme: schemeList) { |
744 | - if(target.toString().startsWith(scheme) == true) { | |
789 | + if(href.startsWith(scheme) == true) { | |
745 | 790 | isExternal = true; |
746 | 791 | break; |
747 | 792 | } |
748 | 793 | } |
749 | - | |
794 | + | |
750 | 795 | return isExternal; |
751 | 796 | } |
752 | 797 |
@@ -773,10 +818,10 @@ public class WikiMainWindowController implements Initializable { | ||
773 | 818 | */ |
774 | 819 | private void internalLinkHandle(EventTarget target) throws Exception { |
775 | 820 | HashMap<String, PageData> pageDataMap; |
776 | - String pageTitle = URLDecoder.decode(target.toString(), "UTF-8"); | |
777 | - | |
778 | - HTMLAnchorElement anchor = (HTMLAnchorElement)target; | |
779 | - String uuid = anchor.getAttribute(WikiEngine.ATTRIBUTE_JCR_UUID); | |
821 | + HTMLAnchorElement anchor = (HTMLAnchorElement)target; | |
822 | + String href = anchor.getAttribute("href"); | |
823 | + String pageTitle = URLDecoder.decode(href, "UTF-8"); | |
824 | + String uuid = anchor.getAttribute(WikiEngine.ATTRIBUTE_JCR_UUID); | |
780 | 825 | |
781 | 826 | if(uuid != null) { |
782 | 827 | pageDataMap = wikiEngine_.queryPageUUID(uuid); |
@@ -789,14 +834,14 @@ public class WikiMainWindowController implements Initializable { | ||
789 | 834 | loadWikiContent(); |
790 | 835 | } |
791 | 836 | else { |
792 | - if(target.toString().contains("#")) { | |
837 | + if(href.contains("#")) { | |
793 | 838 | /* |
794 | 839 | * ページ内セクションリンク |
795 | 840 | */ |
796 | 841 | jumpToSectionLink(target); |
797 | 842 | } |
798 | 843 | else { |
799 | - buildEditView(target.toString()); | |
844 | + buildEditView(href); | |
800 | 845 | } |
801 | 846 | } |
802 | 847 |
@@ -20,12 +20,14 @@ import javax.jcr.NamespaceException; | ||
20 | 20 | import javax.jcr.NamespaceRegistry; |
21 | 21 | import javax.jcr.Node; |
22 | 22 | import javax.jcr.NodeIterator; |
23 | +import javax.jcr.PathNotFoundException; | |
23 | 24 | import javax.jcr.Property; |
24 | 25 | import javax.jcr.Repository; |
25 | 26 | import javax.jcr.RepositoryException; |
26 | 27 | import javax.jcr.Session; |
27 | 28 | import javax.jcr.Value; |
28 | 29 | import javax.jcr.ValueFactory; |
30 | +import javax.jcr.ValueFormatException; | |
29 | 31 | import javax.jcr.Workspace; |
30 | 32 | import javax.jcr.nodetype.NodeType; |
31 | 33 | import javax.jcr.query.Query; |
@@ -213,10 +215,18 @@ public class WikiRepository { | ||
213 | 215 | FileData fileData = pageData.getFileData(); |
214 | 216 | |
215 | 217 | if(fileData != null) { |
216 | - Node fileNode = node.addNode(WikiRepository.NODE_FILE, NodeType.NT_FILE); | |
217 | - Node nodeResource = fileNode.addNode(Property.JCR_CONTENT, NodeType.NT_RESOURCE); | |
218 | + Node fileNode = node.getNode(WikiRepository.NODE_FILE); | |
219 | + | |
220 | + if(fileNode == null) { | |
221 | + fileNode = node.addNode(WikiRepository.NODE_FILE, NodeType.NT_FILE); | |
222 | + fileNode.addNode(Property.JCR_CONTENT, NodeType.NT_RESOURCE); | |
223 | + } | |
224 | + | |
225 | + Node nodeResource = fileNode.getNode(Property.JCR_CONTENT); | |
218 | 226 | |
219 | 227 | ValueFactory valueFactory = session_.getValueFactory(); |
228 | + | |
229 | + | |
220 | 230 | nodeResource.setProperty(Property.JCR_DATA, valueFactory.createBinary(fileData.getInputStream())); |
221 | 231 | nodeResource.setProperty(Property.JCR_MIMETYPE, new StringValue(fileData.getMimeType())); |
222 | 232 | nodeResource.setProperty(Property.JCR_LAST_MODIFIED, valueFactory.createValue(fileData.getLastModified())); |
@@ -228,7 +238,13 @@ public class WikiRepository { | ||
228 | 238 | return node; |
229 | 239 | } |
230 | 240 | |
231 | - public HashMap<String, PageData> executeQuery(String sql) throws Exception { | |
241 | + /** | |
242 | + * Execute query. | |
243 | + * @param sql | |
244 | + * @return HashMap<String, PageData> | |
245 | + * @throws Exception | |
246 | + */ | |
247 | + private HashMap<String, PageData> executeQuery(String sql) throws Exception { | |
232 | 248 | Workspace workspace = session_.getWorkspace(); |
233 | 249 | QueryManager queryMgr = workspace.getQueryManager(); |
234 | 250 | Query query = queryMgr.createQuery(sql, Query.JCR_SQL2); |
@@ -288,6 +304,17 @@ public class WikiRepository { | ||
288 | 304 | title = pageTitle.substring(pageTitle.indexOf(":") + ":".length()); |
289 | 305 | } |
290 | 306 | |
307 | + return queryPageTitle(title, namespace); | |
308 | + } | |
309 | + | |
310 | + /** | |
311 | + * Get node matched page title. | |
312 | + * @param pageTitle | |
313 | + * @param namespace | |
314 | + * @return HashMap<String, PageData> | |
315 | + * @throws Exception | |
316 | + */ | |
317 | + public HashMap<String, PageData> queryPageTitle(String pageTitle, String namespace) throws Exception { | |
291 | 318 | return executeQuery( |
292 | 319 | "SELECT * " |
293 | 320 | + " FROM [nt:unstructured]" |
@@ -297,10 +324,10 @@ public class WikiRepository { | ||
297 | 324 | + " AND" |
298 | 325 | + " [" + PROPERTY_NAMESPACE + "] = '" + namespace + "'" |
299 | 326 | + " AND" |
300 | - + " [" + PROPERTY_TITLE + "] = '" + title + "'" | |
327 | + + " [" + PROPERTY_TITLE + "] = '" + pageTitle + "'" | |
301 | 328 | ); |
302 | 329 | } |
303 | - | |
330 | + | |
304 | 331 | /** |
305 | 332 | * Execute full text search. |
306 | 333 | * @param searchKey |
@@ -383,12 +410,14 @@ public class WikiRepository { | ||
383 | 410 | } |
384 | 411 | else { |
385 | 412 | String uuid = node.getProperty(Property.JCR_UUID).getString(); |
386 | - transformPageDataToNode(pageData, session_.getNodeByIdentifier(uuid)); | |
387 | - session_.save(); | |
413 | + | |
414 | + node = transformPageDataToNode(pageData, session_.getNodeByIdentifier(uuid)); | |
415 | + session_.save(); | |
388 | 416 | } |
389 | 417 | |
390 | 418 | versionMgr.checkin(node.getPath()); |
391 | - | |
419 | + createCategoryPages(node); | |
420 | + | |
392 | 421 | String uuid = node.getProperty(Property.JCR_UUID).getString(); |
393 | 422 | |
394 | 423 | return new PageData(session_.getNodeByIdentifier(uuid)); |
@@ -481,4 +510,61 @@ public class WikiRepository { | ||
481 | 510 | |
482 | 511 | return buf.toString(); |
483 | 512 | } |
513 | + | |
514 | + /** | |
515 | + * | |
516 | + * @param node | |
517 | + * @throws Exception | |
518 | + */ | |
519 | + private void createCategoryPages(Node node) throws Exception { | |
520 | + Workspace workspace = session_.getWorkspace(); | |
521 | + VersionManager versionMgr = workspace.getVersionManager(); | |
522 | + Value[] categories = node.getProperty(PROPERTY_category).getValues(); | |
523 | + | |
524 | + for(Value category: categories) { | |
525 | + String title = category.getString(); | |
526 | + | |
527 | + if(title.isEmpty() != true) { | |
528 | + HashMap<String, PageData> map = queryPageTitle(title, PROPERTY_CATEGORY); | |
529 | + | |
530 | + if(map.size() == 0) { | |
531 | + /* | |
532 | + * category pageが未作成の場合、 | |
533 | + */ | |
534 | + PageData pageData = new PageData(); | |
535 | + pageData.setNamespace(PROPERTY_CATEGORY); | |
536 | + pageData.setTitle(title); | |
537 | + | |
538 | + Node categoryNode = addPageNode(pageData); | |
539 | + session_.save(); | |
540 | + versionMgr.checkout(categoryNode.getPath()); | |
541 | + versionMgr.checkin(categoryNode.getPath()); | |
542 | + } | |
543 | + } | |
544 | + } | |
545 | + } | |
546 | + | |
547 | + /** | |
548 | + * Test namespace is contains namespaceList. | |
549 | + * @param namespace | |
550 | + * @return boolean | |
551 | + * @throws Exception | |
552 | + */ | |
553 | + public boolean isContainsNamespaceList(String namespace) throws Exception { | |
554 | + Node root = session_.getRootNode(); | |
555 | + Node wikiroot = root.getNode(NODE_WIKIROOT); | |
556 | + Node namespaceNode = wikiroot.getNode(NODE_NAMESPACE); | |
557 | + | |
558 | + Value[] list = namespaceNode.getProperty(PROPERTY_NAMESPACE).getValues(); | |
559 | + boolean isContains = false; | |
560 | + | |
561 | + for(Value entry: list) { | |
562 | + if(entry.getString().equals(namespace) == true) { | |
563 | + isContains = true; | |
564 | + break; | |
565 | + } | |
566 | + } | |
567 | + | |
568 | + return isContains; | |
569 | + } | |
484 | 570 | } |
@@ -50,10 +50,16 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
50 | 50 | private static final String IMAGE_END_TAG = "</img>"; |
51 | 51 | |
52 | 52 | /** ページ名接頭辞 "File:" */ |
53 | - private static final String PANGENAME_PREFIX_FILE = "File:"; | |
53 | + private static final String PAGENAME_PREFIX_FILE = WikiEngine.NAMESPACE_FILE + ":"; | |
54 | 54 | |
55 | 55 | /** ページ名接頭辞 ":File:" */ |
56 | - private static final String PANGENAME_PREFIX_COLONFILE = ":File:"; | |
56 | + private static final String PAGENAME_PREFIX_COLONFILE = ":" + WikiEngine.NAMESPACE_FILE + ":"; | |
57 | + | |
58 | + /** ページ名接頭辞 "Category:" */ | |
59 | + private static final String PAGENAME_PREFIX_CATEGORY = WikiEngine.NAMESPACE_CATEGORY + ":"; | |
60 | + | |
61 | + /** ページ名接頭辞 ":Category:" */ | |
62 | + private static final String PAGENAME_PREFIX_COLONCATEGORY = ":" + WikiEngine.NAMESPACE_CATEGORY + ":"; | |
57 | 63 | |
58 | 64 | /** ページタイトルマクロ "#title" */ |
59 | 65 | private static final String PAGENAME_HASH_TITLE = "#title"; |
@@ -72,7 +78,7 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
72 | 78 | NONE, |
73 | 79 | INNERLINK, |
74 | 80 | IMAGERENDER, |
75 | - ATTACHFILE | |
81 | + ATTACHEDFILELINK | |
76 | 82 | }; |
77 | 83 | |
78 | 84 | /** リンクモード */ |
@@ -104,7 +110,14 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
104 | 110 | put(LinkMode.INNERLINK, new TextNodeProcessor() { |
105 | 111 | @Override |
106 | 112 | public void textNodeProcess(StringBuffer buf, String textNode) { |
107 | - buf.append(textNode); | |
113 | + if(linkpath_.isEmpty() != true) { | |
114 | + if( (textNode.startsWith(PAGENAME_PREFIX_COLONFILE) == true) | |
115 | + || (textNode.startsWith(PAGENAME_PREFIX_COLONCATEGORY) == true)) { | |
116 | + textNode = textNode.replaceFirst(Pattern.quote(":"), ""); | |
117 | + } | |
118 | + | |
119 | + buf.append(textNode); | |
120 | + } | |
108 | 121 | } |
109 | 122 | }); |
110 | 123 | } |
@@ -139,22 +152,25 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
139 | 152 | databuf.append(Base64.encode(byteBuf)); |
140 | 153 | } |
141 | 154 | } |
142 | - } | |
143 | - | |
144 | - buf.append(IMAGE_START_TAG); | |
145 | - if(databuf.length() > 0) { | |
146 | - buf.append("\"data:"); | |
147 | - buf.append(mediaType + ";base64 "); | |
148 | - buf.append(databuf); | |
155 | + | |
156 | + buf.append(IMAGE_START_TAG); | |
157 | + if(databuf.length() > 0) { | |
158 | + buf.append("\"data:"); | |
159 | + buf.append(mediaType + ";base64,"); | |
160 | + buf.append(databuf); | |
161 | + buf.append("\""); | |
162 | + } | |
163 | + buf.append(" alt=\""); | |
164 | + buf.append(textNode); | |
149 | 165 | buf.append("\""); |
166 | + buf.append(" title=\""); | |
167 | + buf.append(textNode); | |
168 | + buf.append("\" >"); | |
169 | + buf.append(IMAGE_END_TAG); | |
170 | + } | |
171 | + else { | |
172 | + buf.append(textNode); | |
150 | 173 | } |
151 | - buf.append(" alt=\""); | |
152 | - buf.append(textNode); | |
153 | - buf.append("\""); | |
154 | - buf.append(" title=\""); | |
155 | - buf.append(textNode); | |
156 | - buf.append("\" >"); | |
157 | - buf.append(IMAGE_END_TAG); | |
158 | 174 | } catch (Exception e) { |
159 | 175 | e.printStackTrace(); |
160 | 176 | } |
@@ -162,7 +178,7 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
162 | 178 | }); |
163 | 179 | } |
164 | 180 | { |
165 | - put(LinkMode.ATTACHFILE, new TextNodeProcessor() { | |
181 | + put(LinkMode.ATTACHEDFILELINK, new TextNodeProcessor() { | |
166 | 182 | @Override |
167 | 183 | public void textNodeProcess(StringBuffer buf, String textNode) { |
168 | 184 | String basename = linkpath_.substring(linkpath_.lastIndexOf("\\") + "\\".length()); |
@@ -267,7 +283,7 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
267 | 283 | String deleteTop = line.replaceFirst(Pattern.quote(WIKI_TOKEN_START), ""); |
268 | 284 | String deleteToken = deleteTop.substring(0, deleteTop.lastIndexOf(WIKI_TOKEN_END)); |
269 | 285 | String textNode = deleteToken; |
270 | - | |
286 | + | |
271 | 287 | if(deleteToken.contains("|") == true) { |
272 | 288 | pagename_ = deleteToken.substring(0, deleteToken.indexOf("|")); |
273 | 289 | textNode = deleteToken.substring(deleteToken.indexOf("|") + "|".length()); |
@@ -288,23 +304,25 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
288 | 304 | try { |
289 | 305 | linkpath_ = buildLinkpathFromPagename(pagename_); |
290 | 306 | |
291 | - buf.append(START_TAG); | |
292 | - buf.append("\""); | |
293 | - buf.append(linkpath_ + "\" "); | |
294 | - | |
295 | - HashMap<String, PageData> pageDataMap = wikiRepository_.queryPageTitle(linkpath_); | |
296 | - if(pageDataMap.size() == 0) { | |
297 | - buf.append(STYLE_CLASS_NOEXIST); | |
298 | - } | |
299 | - else if(pageDataMap.size() == 1) { | |
300 | - Set<String> key = pageDataMap.keySet(); | |
301 | - PageData pageData = pageDataMap.get(key.iterator().next()); | |
302 | - Node node = pageData.getNode(); | |
303 | - buf.append(" " + ATTRIBUTE_JCR_UUID + "=\""); | |
304 | - buf.append(node.getProperty(Property.JCR_UUID).getString()); | |
307 | + if(linkpath_.isEmpty() != true) { | |
308 | + buf.append(START_TAG); | |
305 | 309 | buf.append("\""); |
310 | + buf.append(linkpath_ + "\" "); | |
311 | + | |
312 | + HashMap<String, PageData> pageDataMap = wikiRepository_.queryPageTitle(linkpath_); | |
313 | + if(pageDataMap.size() == 0) { | |
314 | + buf.append(STYLE_CLASS_NOEXIST); | |
315 | + } | |
316 | + else if(pageDataMap.size() == 1) { | |
317 | + Set<String> key = pageDataMap.keySet(); | |
318 | + PageData pageData = pageDataMap.get(key.iterator().next()); | |
319 | + Node node = pageData.getNode(); | |
320 | + buf.append(" " + ATTRIBUTE_JCR_UUID + "=\""); | |
321 | + buf.append(node.getProperty(Property.JCR_UUID).getString()); | |
322 | + buf.append("\""); | |
323 | + } | |
324 | + buf.append(">"); | |
306 | 325 | } |
307 | - buf.append(">"); | |
308 | 326 | } catch (Exception e) { |
309 | 327 | e.printStackTrace(); |
310 | 328 | } |
@@ -322,8 +340,10 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
322 | 340 | |
323 | 341 | @Override |
324 | 342 | public void endElementProcess(StringBuffer buf) { |
325 | - buf.append(END_TAG); | |
326 | - linkMode = LinkMode.ATTACHFILE; | |
343 | + if(linkpath_.isEmpty() != true) { | |
344 | + buf.append(END_TAG); | |
345 | + } | |
346 | + linkMode = LinkMode.NONE; | |
327 | 347 | } |
328 | 348 | |
329 | 349 | @Override |
@@ -339,21 +359,21 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
339 | 359 | */ |
340 | 360 | private String buildLinkpathFromPagename(String pagename) throws Exception { |
341 | 361 | String linkpath = null; |
342 | - | |
343 | - if(pagename.startsWith(PANGENAME_PREFIX_COLONFILE) == true) { | |
344 | - linkMode = LinkMode.ATTACHFILE; | |
345 | - linkpath = buildAttachLinkpath(pagename); | |
346 | - } | |
347 | - else if(pagename.startsWith(PANGENAME_PREFIX_FILE) == true) { | |
362 | + | |
363 | + if(pagename.startsWith(PAGENAME_PREFIX_FILE) == true) { | |
348 | 364 | if(FileTypeDeterminator.isImageFile(pagename) == true) { |
349 | 365 | linkMode = LinkMode.IMAGERENDER; |
350 | 366 | linkpath = buildImageLinkpath(pagename); |
351 | 367 | } |
352 | 368 | else { |
353 | - linkMode = LinkMode.ATTACHFILE; | |
369 | + linkMode = LinkMode.ATTACHEDFILELINK; | |
354 | 370 | linkpath = buildAttachLinkpath(pagename); |
355 | 371 | } |
356 | 372 | } |
373 | + else if(pagename.startsWith(PAGENAME_PREFIX_CATEGORY) == true) { | |
374 | + linkMode = LinkMode.INNERLINK; | |
375 | + linkpath = ""; | |
376 | + } | |
357 | 377 | else { |
358 | 378 | linkMode = LinkMode.INNERLINK; |
359 | 379 | linkpath = buildInternalLinkpath(pagename); |
@@ -390,6 +410,11 @@ public class WikiInternalLinkInlineParser extends WikiInlineParserBase { | ||
390 | 410 | * @throws Exception |
391 | 411 | */ |
392 | 412 | private String buildInternalLinkpath(String pagename) throws Exception { |
413 | + if( (pagename.startsWith(PAGENAME_PREFIX_COLONFILE) == true) | |
414 | + || (pagename.startsWith(PAGENAME_PREFIX_COLONCATEGORY) == true)) { | |
415 | + pagename = pagename.replaceFirst(Pattern.quote(":"), ""); | |
416 | + } | |
417 | + | |
393 | 418 | return pagename; |
394 | 419 | } |
395 | 420 | } |
@@ -57,20 +57,6 @@ table td { | ||
57 | 57 | padding-bottom: 0.5em; |
58 | 58 | } |
59 | 59 | |
60 | -table.transparent { | |
61 | - border-collapse: collapse; | |
62 | - border: solid 0px; | |
63 | -} | |
64 | - | |
65 | -table.transparent th, table.transparent td { | |
66 | - background: #ffffff; | |
67 | - border: solid 0px #000000; | |
68 | - padding-left: 1em; | |
69 | - padding-right: 1em; | |
70 | - padding-top: 0.5em; | |
71 | - padding-bottom: 0.5em; | |
72 | -} | |
73 | - | |
74 | 60 | a.noexist { |
75 | 61 | color: #ff8c00; |
76 | 62 | } |
@@ -171,3 +157,11 @@ blockquote.quotation { | ||
171 | 157 | background: #efefef; |
172 | 158 | } |
173 | 159 | |
160 | +div.categorylist { | |
161 | + background: #f0f0f0; | |
162 | + border: solid 1px #c0c0c0; | |
163 | + padding-left: 1em; | |
164 | + padding-right: 1em; | |
165 | + padding-top: 0.5em; | |
166 | + padding-bottom: 0.5em; | |
167 | +} |
@@ -12,4 +12,19 @@ | ||
12 | 12 | |
13 | 13 | #linethrough { |
14 | 14 | text-decoration: line-through; |
15 | -} | |
\ No newline at end of file | ||
15 | +} | |
16 | + | |
17 | +table.transparent { | |
18 | + border-collapse: collapse; | |
19 | + border: solid 0px; | |
20 | +} | |
21 | + | |
22 | +table.transparent th, table.transparent td { | |
23 | + background: #ffffff; | |
24 | + border: solid 0px #000000; | |
25 | + padding-left: 1em; | |
26 | + padding-right: 1em; | |
27 | + padding-top: 0.5em; | |
28 | + padding-bottom: 0.5em; | |
29 | +} | |
30 | + |