Java tutorial
/** * Mogwai ERDesigner. Copyright (C) 2002 The Mogwai Project. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. */ package de.erdesignerng.util; import java.awt.Dimension; import java.awt.HeadlessException; import java.awt.Point; import java.awt.Toolkit; import java.awt.Window; import java.io.File; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; import javax.swing.JFrame; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import de.erdesignerng.model.CascadeType; import de.erdesignerng.visual.EditorMode; /** * Class for handling application preferences, LRU-files and so on. * * @author $Author: mirkosertic $ * @version $Date: 2009-03-13 15:40:33 $ */ public class ApplicationPreferences { private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationPreferences.class); private static final String LRUPREFIX = "file_"; private static final String CLASSPATHPREFIX = "classpath_"; private static final String LRCPREFIX = "lrc_"; private static final String RPCPREFIX = "rpc_"; private static final String GRIDSIZE = "gridsize"; private static final String XMLINDENTATION = "xmlindentation"; private static final String TABLEGRIDWIDTHAFTERREVERSEENGINEERING = "tablegridwidthafterre"; private static final String AUTOMATICRELATIONATTRIBUTEPATTERN = "automaticrelationattributepattern"; private static final String ONUPDATEDEFAULT = "onupdatedefault"; private static final String ONDELETEDEFAULT = "onupdatedefault"; private static final String WINDOWSTATEPREFIX = "windowstate_"; private static final String WINDOWXPREFIX = "windowx_"; private static final String WINDOWYPREFIX = "windowy_"; private static final String WINDOWWIDTHPREFIX = "windowswidth_"; private static final String WINDOWHEIGHTPREFIX = "windowheight_"; private static final String INTELLIGENTLAYOUT = "intelligentlayout_"; private static final String LAYOUT = "layout"; private static final String EDITORMODE = "editormode"; private final int size; private final List<File> recentlyUsedFiles = new ArrayList<>(); private final List<File> classpathfiles = new ArrayList<>(); private final List<ConnectionDescriptor> recentlyUsedConnections = new ArrayList<>(); private final Preferences preferences; private int gridSize; private int xmlIndentation; private ConnectionDescriptor repositoryConnection; private final Map<String, String> windowDefinitions = new HashMap<>(); private File baseDir; private boolean intelligentLayout = true; private String automaticRelationAttributePattern; private CascadeType onUpdateDefault; private CascadeType onDeleteDefault; private byte[] windowLayout; private int gridWidthAfterReverseEngineering; private EditorMode editorMode; private static ApplicationPreferences me; public synchronized static ApplicationPreferences getInstance() { if (me == null) { try { me = new ApplicationPreferences(); } catch (BackingStoreException e) { LOGGER.error("Error loading preferences", e); } } return me; } protected ApplicationPreferences() throws BackingStoreException { preferences = Preferences.userNodeForPackage(ApplicationPreferences.class); List<String> theNames = Arrays.asList(preferences.keys()); for (String theName : theNames) { // Locate the window defaults here if (theName.startsWith("window")) { windowDefinitions.put(theName, preferences.get(theName, null)); } if (theName.startsWith(LRUPREFIX)) { File theFile = new File(preferences.get(theName, "")); if ((theFile.exists()) && (!recentlyUsedFiles.contains(theFile))) { recentlyUsedFiles.add(theFile); } } if (theName.startsWith(CLASSPATHPREFIX)) { File theFile = new File(preferences.get(theName, "")); if (theFile.exists()) { classpathfiles.add(theFile); } } } if (theNames.contains(RPCPREFIX + "DIALECT")) { String theDialect = preferences.get(RPCPREFIX + "DIALECT", ""); String theURL = preferences.get(RPCPREFIX + "URL", ""); String theUser = preferences.get(RPCPREFIX + "USER", ""); String theDriver = preferences.get(RPCPREFIX + "DRIVER", ""); String thePass = preferences.get(RPCPREFIX + "PASS", ""); repositoryConnection = new ConnectionDescriptor(null, theDialect, theURL, theUser, theDriver, thePass, false); } for (int i = 0; i < 20; i++) { if (theNames.contains(LRCPREFIX + "DIALECT_" + i)) { String theAlias = preferences.get(LRCPREFIX + "ALIAS_" + i, ""); String theDialect = preferences.get(LRCPREFIX + "DIALECT_" + i, ""); String theURL = preferences.get(LRCPREFIX + "URL_" + i, ""); String theUser = preferences.get(LRCPREFIX + "USER_" + i, ""); String theDriver = preferences.get(LRCPREFIX + "DRIVER_" + i, ""); String thePass = preferences.get(LRCPREFIX + "PASS_" + i, ""); String thePrompt = preferences.get(LRCPREFIX + "PROMPT_" + i, ""); boolean theBooleanPrompt = false; if (StringUtils.isNotEmpty(thePrompt)) { theBooleanPrompt = Boolean.parseBoolean(thePrompt); } ConnectionDescriptor theConnection = new ConnectionDescriptor(theAlias, theDialect, theURL, theUser, theDriver, thePass, theBooleanPrompt); if (!recentlyUsedConnections.contains(theConnection)) { recentlyUsedConnections.add(theConnection); } } } size = 20; gridSize = preferences.getInt(GRIDSIZE, 10); intelligentLayout = preferences.getBoolean(INTELLIGENTLAYOUT, true); automaticRelationAttributePattern = preferences.get(AUTOMATICRELATIONATTRIBUTEPATTERN, "FK_{0}_{1}"); windowLayout = preferences.getByteArray(LAYOUT, new byte[0]); gridWidthAfterReverseEngineering = preferences.getInt(TABLEGRIDWIDTHAFTERREVERSEENGINEERING, 8); xmlIndentation = preferences.getInt(XMLINDENTATION, 4); onUpdateDefault = CascadeType.fromString(preferences.get(ONUPDATEDEFAULT, CascadeType.NOTHING.toString())); onDeleteDefault = CascadeType.fromString(preferences.get(ONDELETEDEFAULT, CascadeType.NOTHING.toString())); String theMode = preferences.get(EDITORMODE, null); if (theMode == null) { editorMode = EditorMode.CLASSIC; } else { editorMode = EditorMode.valueOf(theMode); } } /** * Add a file to the least recently used (LRU) files list. * * @param aFile the file to add */ public void addRecentlyUsedFile(File aFile) { if (!recentlyUsedFiles.contains(aFile)) { recentlyUsedFiles.add(aFile); if (recentlyUsedFiles.size() > size) { recentlyUsedFiles.remove(0); } } else { recentlyUsedFiles.remove(aFile); recentlyUsedFiles.add(0, aFile); } } /** * Add a last used connection to the list. * * @param aConnection the connection */ public void addRecentlyUsedConnection(ConnectionDescriptor aConnection) { if (!recentlyUsedConnections.contains(aConnection)) { recentlyUsedConnections.add(aConnection); if (recentlyUsedConnections.size() > size) { recentlyUsedConnections.remove(0); } } else { recentlyUsedConnections.remove(aConnection); recentlyUsedConnections.add(0, aConnection); } } public List<File> getRecentlyUsedFiles() { return recentlyUsedFiles; } public List<ConnectionDescriptor> getRecentlyUsedConnections() { return recentlyUsedConnections; } public List<File> getClasspathFiles() { return classpathfiles; } /** * @return the gridSize */ public int getGridSize() { return gridSize; } /** * @param gridSize the gridSize to set */ public void setGridSize(int gridSize) { this.gridSize = gridSize; } /** * Save the preferences. * * @throws BackingStoreException is thrown if the operation fails */ public void store() throws BackingStoreException { String[] theNames = preferences.childrenNames(); for (String theName : theNames) { if (theName.startsWith(LRUPREFIX)) { preferences.remove(theName); } if (theName.startsWith(LRCPREFIX)) { preferences.remove(theName); } if (theName.startsWith(CLASSPATHPREFIX)) { preferences.remove(theName); } if (theName.startsWith(RPCPREFIX)) { preferences.remove(theName); } } for (int i = 0; i < recentlyUsedFiles.size(); i++) { preferences.put(LRUPREFIX + i, recentlyUsedFiles.get(i).toString()); } for (int i = 0; i < recentlyUsedConnections.size(); i++) { ConnectionDescriptor theConnection = recentlyUsedConnections.get(i); if (StringUtils.isNotEmpty(theConnection.getAlias())) { preferences.put(LRCPREFIX + "ALIAS_" + i, theConnection.getAlias()); } preferences.put(LRCPREFIX + "DIALECT_" + i, theConnection.getDialect()); preferences.put(LRCPREFIX + "URL_" + i, theConnection.getUrl()); preferences.put(LRCPREFIX + "USER_" + i, theConnection.getUsername()); preferences.put(LRCPREFIX + "DRIVER_" + i, theConnection.getDriver()); preferences.put(LRCPREFIX + "PASS_" + i, theConnection.getPassword()); preferences.put(LRCPREFIX + "PROMPT_" + i, Boolean.toString(theConnection.isPromptForPassword())); } for (int i = 0; i < classpathfiles.size(); i++) { preferences.put(CLASSPATHPREFIX + i, classpathfiles.get(i).toString()); } preferences.putInt(GRIDSIZE, gridSize); preferences.putInt(XMLINDENTATION, xmlIndentation); preferences.put(AUTOMATICRELATIONATTRIBUTEPATTERN, automaticRelationAttributePattern); preferences.putBoolean(INTELLIGENTLAYOUT, intelligentLayout); preferences.put(ONUPDATEDEFAULT, onUpdateDefault.toString()); preferences.put(ONDELETEDEFAULT, onDeleteDefault.toString()); preferences.putByteArray(LAYOUT, windowLayout); preferences.putInt(TABLEGRIDWIDTHAFTERREVERSEENGINEERING, gridWidthAfterReverseEngineering); if (repositoryConnection != null) { preferences.put(RPCPREFIX + "DIALECT", repositoryConnection.getDialect()); preferences.put(RPCPREFIX + "URL", repositoryConnection.getUrl()); preferences.put(RPCPREFIX + "USER", repositoryConnection.getUsername()); preferences.put(RPCPREFIX + "DRIVER", repositoryConnection.getDriver()); preferences.put(RPCPREFIX + "PASS", repositoryConnection.getPassword()); } for (Map.Entry<String, String> theWindowEntry : windowDefinitions.entrySet()) { preferences.put(theWindowEntry.getKey(), theWindowEntry.getValue()); } preferences.put(EDITORMODE, editorMode.toString()); preferences.flush(); } public ClassLoader createDriverClassLoader() { final URL[] theUrls = new URL[classpathfiles.size()]; for (int i = 0; i < classpathfiles.size(); i++) { try { theUrls[i] = classpathfiles.get(i).toURI().toURL(); } catch (MalformedURLException e) { // This will never happen } } return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> new URLClassLoader(theUrls, Thread.currentThread().getContextClassLoader())); } /** * @return the repositoryConnection */ public ConnectionDescriptor getRepositoryConnection() { return repositoryConnection; } /** * @param repositoryConnection the repositoryConnection to set */ public void setRepositoryConnection(ConnectionDescriptor repositoryConnection) { this.repositoryConnection = repositoryConnection; } /** * Update the last position of a window. * * @param aAlias the alias of the window * @param aWindow the window */ public void updateWindowDefinition(String aAlias, JFrame aWindow) { windowDefinitions.put(WINDOWSTATEPREFIX + aAlias, "" + aWindow.getExtendedState()); updateWindowLocation(aAlias, aWindow); updateWindowSize(aAlias, aWindow); } /** * Set the current window state as stored by updateWindowDefinition. * * @param aAlias the alias of the window * @param aFrame the window */ public void setWindowState(String aAlias, JFrame aFrame) { if (windowDefinitions.containsKey(WINDOWSTATEPREFIX + aAlias)) { try { aFrame.setExtendedState(Integer.parseInt(windowDefinitions.get(WINDOWSTATEPREFIX + aAlias))); setWindowLocation(aAlias, aFrame); setWindowSize(aAlias, aFrame); } catch (NumberFormatException e) { aFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); } } } public void updateWindowLocation(String aAlias, Window aWindow) { Point theLocation = aWindow.getLocation(); windowDefinitions.put(WINDOWXPREFIX + aAlias, "" + theLocation.x); windowDefinitions.put(WINDOWYPREFIX + aAlias, "" + theLocation.y); } public void updateWindowSize(String aAlias, Window aWindow) { Dimension theSize = aWindow.getSize().getSize(); windowDefinitions.put(WINDOWWIDTHPREFIX + aAlias, "" + theSize.width); windowDefinitions.put(WINDOWHEIGHTPREFIX + aAlias, "" + theSize.height); } public void setWindowSize(String aAlias, Window aWindow) { try { int width = Integer.parseInt(windowDefinitions.get(WINDOWWIDTHPREFIX + aAlias)); int height = Integer.parseInt(windowDefinitions.get(WINDOWHEIGHTPREFIX + aAlias)); aWindow.setSize(width, height); } catch (NumberFormatException e) { // If no old size is known, an Exception is thrown // This can be ignored } } public void setWindowLocation(String aAlias, Window aWindow) { try { int x = Integer.parseInt(windowDefinitions.get(WINDOWXPREFIX + aAlias)); int y = Integer.parseInt(windowDefinitions.get(WINDOWYPREFIX + aAlias)); // Only set the size and location if its within the available // screen resolution Dimension theCurrentScreenSize = Toolkit.getDefaultToolkit().getScreenSize(); if (x < theCurrentScreenSize.width && y < theCurrentScreenSize.height) { aWindow.setLocation(x, y); } } catch (HeadlessException | NumberFormatException e) { // If no old location is known, an Exception is thrown // This can be ignored } } /** * @return the baseDir */ public File getBaseDir() { return baseDir; } /** * @param baseDir the baseDir to set */ public void setBaseDir(File baseDir) { this.baseDir = baseDir; } /** * @return the intelligentLayout */ public boolean isIntelligentLayout() { return intelligentLayout; } /** * @param intelligentLayout the intelligentLayout to set */ public void setIntelligentLayout(boolean intelligentLayout) { this.intelligentLayout = intelligentLayout; } public File getRelativeFile(String aName) { if (baseDir != null) { return new File(baseDir, aName); } return new File(aName); } /** * Get the directory where the report templates are located. * * @return the directory */ public File getReportsDirectory() { return getRelativeFile("reports"); } /** * Test if we are running in development mode. * * @return true, if in development mode; false else */ public boolean isInDevelopmentMode() { String theVersionNumber = MavenPropertiesLocator.getERDesignerVersionInfo(); return theVersionNumber.equals(MavenPropertiesLocator.CANNOT_IDENTIFY_VERSION); } /** * Get the directory where the datatype configuration is located. * * @return the directory */ public File getDatatypeConfigDirectory() { File theUserHomeFile = SystemUtils.getUserHome(); if (theUserHomeFile == null) { return getRelativeFile("dataTypes"); } String theVersionNumber = MavenPropertiesLocator.getERDesignerVersionInfo(); if (theVersionNumber.equals(MavenPropertiesLocator.CANNOT_IDENTIFY_VERSION)) { theVersionNumber = "development"; } theVersionNumber = theVersionNumber.replace(".", "_"); theVersionNumber = theVersionNumber.replace(" ", "_"); theVersionNumber = theVersionNumber.replace("-", "_"); File theMogwaiHome = new File(theUserHomeFile, ".mogwai"); File theVersionHome = new File(theMogwaiHome, theVersionNumber); return new File(theVersionHome, "dataTypes"); } /** * Get the online help pdf file. * * @return the file * @throws java.lang.Exception */ public URI getOnlineHelpPDFFile() throws Exception { return new URL("http://mogwai.sourceforge.net/userdoc/MogwaiERDesignerNG.pdf").toURI(); } public String getAutomaticRelationAttributePattern() { return automaticRelationAttributePattern; } public void setAutomaticRelationAttributePattern(String automaticRelationAttributePattern) { this.automaticRelationAttributePattern = automaticRelationAttributePattern; } public CascadeType getOnUpdateDefault() { return onUpdateDefault; } public void setOnUpdateDefault(CascadeType onUpdateDefault) { this.onUpdateDefault = onUpdateDefault; } public CascadeType getOnDeleteDefault() { return onDeleteDefault; } public void setOnDeleteDefault(CascadeType onDeleteDefault) { this.onDeleteDefault = onDeleteDefault; } public byte[] getWindowLayout() { return windowLayout; } public void setWindowLayout(byte[] windowLayout) { this.windowLayout = windowLayout; } public int getGridWidthAfterReverseEngineering() { return gridWidthAfterReverseEngineering; } public void setGridWidthAfterReverseEngineering(int gridWidthAfterReverseEngineering) { this.gridWidthAfterReverseEngineering = gridWidthAfterReverseEngineering; } public int getXmlIndentation() { return xmlIndentation; } public void setXmlIndentation(int xmlIndentation) { this.xmlIndentation = xmlIndentation; } public EditorMode getEditorMode() { return editorMode; } public void setEditorMode(EditorMode editorMode) { this.editorMode = editorMode; } }