PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/de/muenchen/allg/itd51/wollmux/Workarounds.java

https://bitbucket.org/banbury/wollmux
Java | 532 lines | 255 code | 39 blank | 238 comment | 74 complexity | 40eb576cf9e1cefeb1d59b5a9269cd52 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause-No-Nuclear-License-2014, AGPL-3.0
  1. /*
  2. * Dateiname: Workarounds.java
  3. * Projekt : WollMux
  4. * Funktion : Referenziert alle temporären Workarounds an einer zentralen Stelle
  5. *
  6. * Copyright (c) 2009 Landeshauptstadt München
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the European Union Public Licence (EUPL),
  10. * version 1.0 (or any later version).
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * European Union Public Licence for more details.
  16. *
  17. * You should have received a copy of the European Union Public Licence
  18. * along with this program. If not, see
  19. * http://ec.europa.eu/idabc/en/document/7330
  20. *
  21. * Änderungshistorie:
  22. * Datum | Wer | Änderungsgrund
  23. * -------------------------------------------------------------------
  24. * 01.04.2009 | LUT | Erstellung
  25. * -------------------------------------------------------------------
  26. *
  27. * @author Christoph Lutz (D-III-ITD-D101)
  28. * @version 1.0
  29. *
  30. */package de.muenchen.allg.itd51.wollmux;
  31. import java.awt.MouseInfo;
  32. import java.awt.Point;
  33. import java.awt.PointerInfo;
  34. import java.awt.Robot;
  35. import java.net.URL;
  36. import java.net.URLClassLoader;
  37. import java.util.regex.Pattern;
  38. import javax.swing.JOptionPane;
  39. import com.sun.star.container.XNameAccess;
  40. import com.sun.star.lang.XMultiServiceFactory;
  41. import de.muenchen.allg.afid.UNO;
  42. import de.muenchen.allg.afid.UnoProps;
  43. /**
  44. * Diese Klasse referenziert alle temporären Workarounds, die im WollMux aufgenommen
  45. * wurden, an einer zentralen Stelle. Sie definiert Methoden, die die Steuerung
  46. * übernehmen, ob ein Workaround anzuwenden ist oder nicht.
  47. *
  48. * @author Christoph Lutz (D-III-ITD-D101)
  49. */
  50. public class Workarounds
  51. {
  52. /**
  53. * Enthält die Version des eingesetzten OpenOffice.org, die mit
  54. * {@link #getOOoVersion()} abgefragt werden kann.
  55. */
  56. private static String oooVersion = null;
  57. /*
  58. * Das ".*" nach dem \\A dürfte da eigentlich nicht sein, aber wenn es nicht da
  59. * ist, wird bei der Abtretungserklärung gemeckert wegen des Issues 101249.
  60. */
  61. private static final Pattern INSERTFORMVALUE_BOOKMARK_TEXT_THAT_CAN_BE_SAFELY_DELETED_WORKAROUND =
  62. Pattern.compile("\\A.*[<\\[{].*[\\]>}]\\z");
  63. private static Boolean workaround100374 = null;
  64. private static Pattern workaround101249 = null;
  65. private static String workaround101283 = null;
  66. private static Boolean workaround103137 = null;
  67. private static Boolean workaroundToolbarHoverFreeze = null;
  68. private static Boolean workaround102164 = null;
  69. private static Boolean workaround73229 = null;
  70. private static Boolean workaround96281 = null;
  71. private static Boolean workaround102619 = null;
  72. private static ClassLoader workaround102164CL = null;
  73. private static Boolean workaround68261 = null;
  74. private static Boolean applyWorkaround(String issueNumber)
  75. {
  76. Logger.debug("Workaround für Issue "
  77. + issueNumber
  78. + " aktiv. Bestimmte Features sind evtl. nicht verfügbar. Die Performance kann ebenfalls leiden.");
  79. return Boolean.TRUE;
  80. }
  81. /**
  82. * Issue #100374 betrifft OOo 3.0.x. Der Workaround kann entfernt werden, wenn
  83. * voraussichtlich OOo 3.1 flächendeckend eingesetzt wird.
  84. *
  85. * @author Matthias Benkmann (D-III-ITD-D101)
  86. */
  87. public static boolean applyWorkaroundForOOoIssue100374()
  88. {
  89. if (workaround100374 == null)
  90. {
  91. String version = getOOoVersion();
  92. // -100374 ist der Marker für unsere selbst gepatchten Versionen ohne den
  93. // Fehler
  94. if (version != null && version.startsWith("3.0")
  95. && !version.contains("-100374"))
  96. {
  97. workaround100374 = applyWorkaround("100374");
  98. }
  99. else
  100. workaround100374 = Boolean.FALSE;
  101. }
  102. return workaround100374.booleanValue();
  103. }
  104. /**
  105. * Issue #73229 betrifft den WollMux-Seriendruck in ein Gesamtdokument und ist
  106. * aktuell für OOo Later priorisiert - wird also nicht in absehbarer Zeit behoben
  107. * sein.
  108. *
  109. * @author Christoph Lutz (D-III-ITD-D101)
  110. */
  111. public static boolean applyWorkaroundForOOoIssue73229()
  112. {
  113. if (workaround73229 == null)
  114. {
  115. workaround73229 = applyWorkaround("73229");
  116. }
  117. return workaround73229.booleanValue();
  118. }
  119. /**
  120. * Issue #102164 betrifft OOo 3.2. Es ist unklar, wann der Workaround entfernt
  121. * werden kann, da er aufgrund eines Bugs in der Swing-Implementierung von Java 6
  122. * zurückgeht.
  123. *
  124. * @author Matthias Benkmann (D-III-ITD-D101)
  125. */
  126. public static void applyWorkaroundForOOoIssue102164()
  127. {
  128. if (workaround102164 == null)
  129. {
  130. String version = getOOoVersion();
  131. if (version != null && !version.startsWith("3.1") && !version.startsWith("2")
  132. && !version.startsWith("3.0"))
  133. {
  134. workaround102164 = applyWorkaround("102164");
  135. }
  136. else
  137. workaround102164 = Boolean.FALSE;
  138. }
  139. if (workaround102164.booleanValue())
  140. {
  141. if (workaround102164CL == null)
  142. workaround102164CL = Thread.currentThread().getContextClassLoader();
  143. if (workaround102164CL == null)
  144. workaround102164CL = Workarounds.class.getClassLoader();
  145. if (workaround102164CL == null)
  146. workaround102164CL = ClassLoader.getSystemClassLoader();
  147. if (workaround102164CL == null)
  148. workaround102164CL = new URLClassLoader(new URL[] {});
  149. Thread.currentThread().setContextClassLoader(workaround102164CL);
  150. }
  151. }
  152. /**
  153. * Issue #103137 betrifft OOo 3.0 und 3.1. Der Workaround kann entfernt werden,
  154. * wenn keine Dokumente mehr im Umlauf sind, deren Generator OOo 2 ist und in denen
  155. * Textstellen mindestens einmal aus- und wieder eingeblendet wurden. Notfalls muss
  156. * man vor der Deaktivierung einen Mechanismus über die Dokumentablagen der
  157. * Referate laufen lassen der dafür sorgt, dass der Altbestand der von OOo 2
  158. * erzeugten Dokumente von sämtlichen text:display="none"-Stellen befreit wurde.
  159. *
  160. * @author Christoph Lutz (D-III-ITD-D101)
  161. */
  162. public static boolean applyWorkaroundForOOoIssue103137()
  163. {
  164. if (workaround103137 == null)
  165. {
  166. String version = getOOoVersion();
  167. if (version != null
  168. && (version.startsWith("3.0") || version.startsWith("3.1")))
  169. {
  170. workaround103137 = applyWorkaround("103137");
  171. }
  172. else
  173. workaround103137 = Boolean.FALSE;
  174. }
  175. return workaround103137.booleanValue();
  176. }
  177. /**
  178. * Issue #96281 betrifft OOo 3.1 und 3.2. Ob es in 3.3 gelöst sein wird wissen wir
  179. * nicht. Seien wir einfach mal pessimistisch.
  180. *
  181. * @author Matthias Benkmann (D-III-ITD-D101)
  182. */
  183. public static boolean applyWorkaroundForOOoIssue96281()
  184. {
  185. if (workaround96281 == null)
  186. {
  187. String version = getOOoVersion();
  188. if (version != null
  189. && (version.startsWith("3.1") || version.startsWith("3.2") || version.startsWith("3.3")))
  190. {
  191. workaround96281 = applyWorkaround("96281");
  192. }
  193. else
  194. workaround96281 = Boolean.FALSE;
  195. }
  196. return workaround96281.booleanValue();
  197. }
  198. /**
  199. * Diese Methode liefert die Versionsnummer von OpenOffice.org aus dem
  200. * Konfigurationsknoten /org.openoffice.Setup/Product/oooSetupVersionAboutBox
  201. * konkateniert mit /org.openoffice.Setup/Product/oooSetupExtension zurück oder
  202. * null, falls bei der Bestimmung der Versionsnummer Fehler auftraten.
  203. *
  204. * @author Christoph Lutz (D-III-ITD-D101)
  205. */
  206. public static String getOOoVersion()
  207. {
  208. if (oooVersion == null)
  209. {
  210. XMultiServiceFactory cfgProvider =
  211. UNO.XMultiServiceFactory(UNO.createUNOService("com.sun.star.configuration.ConfigurationProvider"));
  212. if (cfgProvider != null)
  213. {
  214. XNameAccess cfgAccess = null;
  215. try
  216. {
  217. cfgAccess =
  218. UNO.XNameAccess(cfgProvider.createInstanceWithArguments(
  219. "com.sun.star.configuration.ConfigurationAccess", new UnoProps(
  220. "nodepath", "/org.openoffice.Setup/Product").getProps()));
  221. }
  222. catch (Exception e)
  223. {}
  224. if (cfgAccess != null)
  225. {
  226. try
  227. {
  228. oooVersion =
  229. "" + cfgAccess.getByName("ooSetupVersionAboutBox")
  230. + cfgAccess.getByName("ooSetupExtension");
  231. }
  232. catch (Exception e)
  233. {}
  234. }
  235. }
  236. }
  237. return oooVersion;
  238. }
  239. /**
  240. * Wegen http://qa.openoffice.org/issues/show_bug.cgi?id=101249 muss ein laxeres
  241. * Pattern verwendet werden, zum Test, ob ein Text in einem insertFormValue
  242. * Bookmark problematisch ist.
  243. *
  244. * @return das Pattern das zum Testen verwendet werden soll
  245. * @author Matthias Benkmann (D-III-ITD-D101)
  246. */
  247. public static Pattern workaroundForIssue101249()
  248. {
  249. if (workaround101249 == null)
  250. {
  251. Logger.debug(L.m("Workaround für Issue 101249 aktiv."));
  252. workaround101249 =
  253. INSERTFORMVALUE_BOOKMARK_TEXT_THAT_CAN_BE_SAFELY_DELETED_WORKAROUND;
  254. }
  255. return workaround101249;
  256. }
  257. /**
  258. * Wegen http://qa.openoffice.org/issues/show_bug.cgi?id=101283 muss der Inhalt des
  259. * Bookmarks durch ein Leerzeichen an Stelle des gewünschten Leerstrings ersetzt
  260. * werden.
  261. *
  262. * @return Der String, der an Stelle des gewünschten Leerstrings zur Behebung des
  263. * Workarounds verwendet werden muss.
  264. *
  265. * @author Christoph Lutz (D-III-ITD-D101)
  266. */
  267. public static String workaroundForIssue101283()
  268. {
  269. if (workaround101283 == null)
  270. {
  271. Logger.debug(L.m("Workaround für Issue 101283 aktiv."));
  272. workaround101283 = " ";
  273. }
  274. return workaround101283;
  275. }
  276. /**
  277. * Wenn bestimmte Aktionen getätigt werden (z.B. setWindowPosSize()) während der
  278. * Mauszeiger über einer OOo-Toolbar schwebt, dann friert OOo 3.0 und 3.1 unter
  279. * Windows ein.
  280. *
  281. * @author Matthias Benkmann (D-III-ITD-D101)
  282. */
  283. public static boolean workaroundForToolbarHoverFreeze()
  284. {
  285. if (workaroundToolbarHoverFreeze == null)
  286. {
  287. String version = getOOoVersion();
  288. if (version == null) return false;
  289. if ((version.startsWith("3.0") || version.startsWith("3.1"))
  290. && System.getProperty("os.name").contains("Windows"))
  291. {
  292. workaroundToolbarHoverFreeze = applyWorkaround("ToolbarHoverFreeze");
  293. }
  294. else
  295. workaroundToolbarHoverFreeze = Boolean.FALSE;
  296. }
  297. if (workaroundToolbarHoverFreeze)
  298. {
  299. try
  300. {
  301. Robot robot = new Robot();
  302. PointerInfo info = MouseInfo.getPointerInfo();
  303. Point p = info.getLocation();
  304. robot.mouseMove(p.x, 0);
  305. Thread.sleep(100);
  306. }
  307. catch (Exception x)
  308. {
  309. Logger.error(x);
  310. }
  311. }
  312. return workaroundToolbarHoverFreeze;
  313. }
  314. /**
  315. * Prüft, ob das Programm mit Java 5 ausgeführt wird, und liefert <code>true</code>
  316. * zurück, wenn dies der Fall ist. Wenn showMessage=true übergeben wird, wird
  317. * außerdem ein Meldungsdialog angezeigt, der darauf hinweist dass das gewünschte
  318. * Feature nicht mit Java 5 ausgeführt werden kann und es wird eine entsprechende
  319. * Meldung geloggt.
  320. *
  321. * Es wird explizit nur auf Java 1.5 geprüft, da Java-Versionen kleiner 1.5 ohnehin
  322. * nicht vom WollMux unterstützt werden. Der Check auf die Systemproperty
  323. * "java.version" ist freilich nicht der sicherste, da diese Variable z.B. auch vom
  324. * Benutzer überschrieben werden kann, aber für unsere Zwecke sollte er in 99,9%
  325. * der Fälle ausreichend sein.
  326. *
  327. * @param featureName
  328. * Name des Features, das nicht mit Java 5 ausgeführt werden kann. Dieser
  329. * String wird in der Log-Meldung verwendet.
  330. * @param showMessage
  331. * Falls <code>true</code> wird eine benutzersichtbare Meldung angezeigt,
  332. * die darauf hinweist, dass ein Feature nicht mit Java 5 ausführbar ist
  333. * und eine Meldung geloggt.
  334. * @return <code>true</code>, wenn das Programm mit Java 5 ausgeführt wird,
  335. * <code>false</code> sonst
  336. * @author Daniel Benkmann (D-III-ITD-D101)
  337. */
  338. public static boolean workaroundForJava5(String featureName, boolean showMessage)
  339. {
  340. if (System.getProperty("java.version").startsWith("1.5"))
  341. {
  342. if (showMessage)
  343. {
  344. Logger.debug(L.m(
  345. "Versuch das Feature \"%1\" mit Java 5 zu starten wurde verhindert.",
  346. featureName));
  347. JOptionPane.showMessageDialog(
  348. null,
  349. L.m("Dieses Feature ist nur verfügbar, wenn Java 6 oder höher eingesetzt wird."),
  350. L.m("Inkompatible Java-Version"), JOptionPane.ERROR_MESSAGE);
  351. }
  352. return true;
  353. }
  354. return false;
  355. }
  356. /**
  357. * Trac-Ticket 5031 beschreibt mehrere Fälle, in denen WollMux-Formulardokumente
  358. * aus bisher unbekanntem Grund ihren Formularwerteabschnitt verloren haben. In
  359. * einem Fall enthielt ein Formulardokument gar keine Notiz "WollMuxFormularwerte",
  360. * ein anderes Formulardokument enthielt eine solche Notiz aber mit leerem
  361. * Dateninhalt, wiederum eine andere Notiz enthielt eine leere Notiz ohne
  362. * dc:creator-Attribut, die mutmaßlich früher einmal eine
  363. * WollMuxFormularwerte-Notiz war.
  364. *
  365. * Falls das Dokument vor dieser Verarbeitung durch den WollMux bereits einmal
  366. * durch den WollMux als Formulardokument markiert worden ist, entsteht ein nicht
  367. * zulässiger Zustand, wenn der Formularwerte-Abschnitt fehlt. Diese Methode
  368. * liefert true, wenn der Fall vorliegt und ein entsprechender Workaround
  369. * angewendet werden soll.
  370. *
  371. * Da die Ursache, die zu dem nicht zulässigen Stand geführt hat derzeit noch nicht
  372. * bekannt ist, und die Symptome auch in drei Fällen unterschiedlich waren (s.o.),
  373. * kann dieser Workaround derzeit leider nicht zeitlich beschränkt werden. Die
  374. * Vermutung liegt nahe, dass der Fehler im Zusammenhang mit den OOo-Issues 100374
  375. * und 108709 (also den Änderungen an OOo 3.0 bezüglich des Notizen-Systems)
  376. * zusammen hängt. Die Hoffnung ist, dass solche kaputten Dokumente nicht mehr
  377. * auftreten, wenn diese beiden Fehler gefixed sind.
  378. *
  379. * @param werteStr
  380. * Den Wert den PersistantData zur ID "WollMuxFormularwerte" zurück gibt
  381. * (kann null sein, wenn die Notiz bisher nicht existiert, oder != null,
  382. * wenn sie bereits existiert).
  383. * @param alreadyTouchedAsFormDocument
  384. * Gibt an, ob das Dokument vor dieser Verarbeitung durch den WollMux
  385. * bereits Formulardokument-Merkmale enthielt (z.B. eine Notiz SetType mit
  386. * dem Wert "formularDokument")
  387. * @return true, wenn der Workaround anzuwenden ist.
  388. *
  389. * @author Christoph Lutz (D-III-ITD-D101)
  390. */
  391. public static boolean applyWorkaroundForTracTicket5031(String werteStr,
  392. boolean alreadyTouchedAsFormDocument)
  393. {
  394. boolean apply =
  395. alreadyTouchedAsFormDocument && (werteStr == null || werteStr.length() == 0);
  396. if (apply)
  397. Logger.log(L.m("Formulardokument ohne Formularwerte-Abschnitt gefunden! Workaround zur Rekonstruierung der Formularwerte aktiv."));
  398. return apply;
  399. }
  400. /**
  401. * Issue 102619 (calling dispatch .uno:GotoNextPlacemarker crashes OOo) beschreibt
  402. * einen Bug in OOo < 3.2.1 bei dem OOo crashed, wenn mittels des Dispatches
  403. * .uno:GotoNextPlacemarker in eine Tabelle navigiert wird.
  404. *
  405. * @author Christoph Lutz (D-III-ITD-D101)
  406. */
  407. public static boolean applyWorkaroundForOOoIssue102619()
  408. {
  409. if (workaround102619 == null)
  410. {
  411. String version = getOOoVersion();
  412. if (version != null
  413. && (version.startsWith("2.") || version.startsWith("3.0") || version.startsWith("3.1")))
  414. {
  415. workaround102619 = applyWorkaround("102619");
  416. }
  417. else
  418. workaround102619 = Boolean.FALSE;
  419. }
  420. return workaround102619.booleanValue();
  421. }
  422. /**
  423. * Issue 68261 (XEnumeration.nextElement() throws despite hasMoreElements()==true)
  424. * beschreibt einen Bug in OOo < 3.0 (das genaue Target der 2er-Serie kann ich
  425. * leider nicht mehr ermitteln) bei dem OOo Exceptions schmeißt beim Iterieren über
  426. * Inhalte in Tabellen.
  427. *
  428. * Achtung: Sollte der Workaround einmal entfernt werden, dann bitte darauf achten,
  429. * dass sich der Workaround nicht nur auf den im Code markierten Block bezieht,
  430. * sondern sich durch die ganze Logik in der Klasse {@link FormFieldFactory}
  431. * durchzieht. Die Logik dieser Klasse kann an einigen Stellen sicherlich deutlich
  432. * vereinfacht werden ohne diesen Workaround. Evtl. bietet sich sogar ein
  433. * Neu-Schreiben an.
  434. *
  435. * @author Christoph Lutz (D-III-ITD-D101)
  436. */
  437. public static boolean applyWorkaroundForOOoIssue68261()
  438. {
  439. if (workaround68261 == null)
  440. {
  441. String version = getOOoVersion();
  442. if (version != null && (version.startsWith("2.")))
  443. {
  444. workaround68261 = applyWorkaround("68261");
  445. }
  446. else
  447. workaround68261 = Boolean.FALSE;
  448. }
  449. return workaround68261.booleanValue();
  450. }
  451. // Unbenutzer alternativer Workaround für das setWindowPosSizeFreeze Problem
  452. // /**
  453. // * setWindowPosSize() aus einem Java-Thread (nicht Beanshell) heraus friert unter
  454. // * Windows OOo ein.
  455. // *
  456. // *
  457. // * @author Matthias Benkmann (D-III-ITD-D101)
  458. // */
  459. // public static boolean workaroundForSetWindowPosSizeFreeze(JFrame frame)
  460. // {
  461. // if (workaroundSetWindowPosSize == null)
  462. // {
  463. // String version = getOOoVersion();
  464. // if (version != null
  465. // && (version.startsWith("3.0") || version.startsWith("3.1"))
  466. // && System.getProperty("os.name").contains("Windows"))
  467. // {
  468. // workaroundSetWindowPosSize = applyWorkaround("setWindowPosSize");
  469. // }
  470. // else
  471. // workaroundSetWindowPosSize = Boolean.FALSE;
  472. // }
  473. //
  474. // if (workaroundSetWindowPosSize.booleanValue())
  475. // {
  476. // try
  477. // {
  478. // if (frame.isActive()) return true;
  479. // PointerInfo info = MouseInfo.getPointerInfo();
  480. // Rectangle r = frame.getBounds();
  481. // if (!r.contains(info.getLocation()))
  482. // new Robot().mouseMove(r.x + r.width / 2, r.y + r.height / 2);
  483. // }
  484. // catch (Exception x)
  485. // {
  486. // Logger.error(x);
  487. // }
  488. // return true;
  489. // }
  490. //
  491. // return false;
  492. // }
  493. }