From b7085203640ff4fae2e6558955ebe88950969208 Mon Sep 17 00:00:00 2001 From: Luiz Victor Linhares Rocha Date: Mon, 17 Oct 2016 16:41:17 -0200 Subject: [PATCH] adds documentation and refactoring for many files --- .../sf/openrocket/appearance/Appearance.java | 4 +- .../net/sf/openrocket/appearance/Decal.java | 47 ++- .../sf/openrocket/appearance/DecalImage.java | 24 ++ .../defaults/DefaultAppearance.java | 40 ++ .../defaults/ResourceDecalImage.java | 11 +- .../openrocket/communication/UpdateInfo.java | 14 +- .../communication/UpdateInfoRetriever.java | 352 +++++++++++++----- .../database/AsynchronousDatabaseLoader.java | 32 +- .../database/ComponentPresetDao.java | 37 +- .../net/sf/openrocket/database/Database.java | 31 +- .../openrocket/database/DatabaseListener.java | 15 + .../net/sf/openrocket/database/Databases.java | 58 ++- .../database/motor/ThrustCurveMotorSet.java | 230 ++++++++---- .../sf/openrocket/document/Attachment.java | 19 + .../sf/openrocket/document/DecalRegistry.java | 9 + .../rocketcomponent/AxialStage.java | 40 +- .../rocketcomponent/RocketComponent.java | 8 +- 17 files changed, 744 insertions(+), 227 deletions(-) diff --git a/core/src/net/sf/openrocket/appearance/Appearance.java b/core/src/net/sf/openrocket/appearance/Appearance.java index 385256bb6..e9271491c 100644 --- a/core/src/net/sf/openrocket/appearance/Appearance.java +++ b/core/src/net/sf/openrocket/appearance/Appearance.java @@ -23,9 +23,7 @@ public class Appearance { } public Appearance(final Color paint, final double shine) { - this.paint = paint; - this.shine = MathUtil.clamp(shine, 0, 1); - this.texture = null; + this(paint,shine,null); } public Color getPaint() { diff --git a/core/src/net/sf/openrocket/appearance/Decal.java b/core/src/net/sf/openrocket/appearance/Decal.java index 5e5461188..412cdcd3d 100644 --- a/core/src/net/sf/openrocket/appearance/Decal.java +++ b/core/src/net/sf/openrocket/appearance/Decal.java @@ -4,12 +4,17 @@ import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.Coordinate; /** - * A texture that can be applied by an Appearance. This class is immutable. + * A texture that can be applied by an Appearance. an object of this class is immutable. * * @author Bill Kuker */ public class Decal { + /** + * enum to flag what happens on edge in a decal + * + * + */ public static enum EdgeMode { REPEAT("TextureWrap.Repeat"), MIRROR("TextureWrap.Mirror"), CLAMP("TextureWrap.Clamp"), STICKER("TextureWrap.Sticker"); private final String transName; @@ -29,6 +34,16 @@ public class Decal { private final DecalImage image; private final EdgeMode mode; + /** + * Builds a new decal with the given itens + * + * @param offset The offset of the decal, in coordinate obejct format + * @param center The position of the center of the decal, in coordinate object format + * @param scale The scale of the decal, in coordinate obejct format + * @param rotation Rotation of the decal, in radians + * @param image The image itself + * @param mode The description of Edge behaviour + */ public Decal(final Coordinate offset, final Coordinate center, final Coordinate scale, final double rotation, final DecalImage image, final EdgeMode mode) { this.offset = offset; @@ -39,26 +54,56 @@ public class Decal { this.mode = mode; } + /** + * returns the offset, in coordinates object format + * + * @return offset coordinates of the decal + */ public Coordinate getOffset() { return offset; } + /** + * return the center, in coordinates object format + * + * @return The center coordinates of the decal + */ public Coordinate getCenter() { return center; } + /** + * return the scaling of the decal, in coordinate format + * + * @return the scale coordinates of the decal + */ public Coordinate getScale() { return scale; } + /** + * returns the rotation of the decal, in radians + * + * @return the rotation of the decal, in radians + */ public double getRotation() { return rotation; } + /** + * return the edge behaviour of the decal + * + * @return the edge behaviour of the decal + */ public EdgeMode getEdgeMode() { return mode; } + /** + * returns the image of the decal itself + * + * @return the image of the decal itself + */ public DecalImage getImage() { return image; } diff --git a/core/src/net/sf/openrocket/appearance/DecalImage.java b/core/src/net/sf/openrocket/appearance/DecalImage.java index 544eda8b3..77a74010f 100644 --- a/core/src/net/sf/openrocket/appearance/DecalImage.java +++ b/core/src/net/sf/openrocket/appearance/DecalImage.java @@ -7,13 +7,37 @@ import java.io.InputStream; import net.sf.openrocket.util.ChangeSource; +/** + * Interface to handle image files for declas + * + */ public interface DecalImage extends ChangeSource, Comparable { + /** + * returns the name of the file path of the image + * @return name of file path + */ public String getName(); + /** + * gets the Stream of bytes representing the image itself + * + * @return the Stream of bytes representing the image + * @throws FileNotFoundException + * @throws IOException + */ public InputStream getBytes() throws FileNotFoundException, IOException; + /** + * exports an image into the File + * @param file The File handler object + * @throws IOException + */ public void exportImage(File file) throws IOException; + /** + * wake up call to listeners + * @param source The source of the wake up call + */ public void fireChangeEvent(Object source); } diff --git a/core/src/net/sf/openrocket/appearance/defaults/DefaultAppearance.java b/core/src/net/sf/openrocket/appearance/defaults/DefaultAppearance.java index 38806be53..bd57cc94a 100644 --- a/core/src/net/sf/openrocket/appearance/defaults/DefaultAppearance.java +++ b/core/src/net/sf/openrocket/appearance/defaults/DefaultAppearance.java @@ -23,8 +23,22 @@ import net.sf.openrocket.rocketcomponent.TubeFinSet; import net.sf.openrocket.util.Color; import net.sf.openrocket.util.Coordinate; +/** + * + * Class defining the default images of the application + * + */ public class DefaultAppearance { + /** + * returns a simple appearance with the image in the path with + * default color + * no shining + * no offset, origin center and scale 1 + * + * @param resource the path file to the resource + * @return + */ private static Appearance simple(String resource) { return new Appearance( new Color(1, 1, 1), @@ -37,6 +51,14 @@ public class DefaultAppearance { new ResourceDecalImage(resource), EdgeMode.REPEAT)); }; + /** + * returns the image with custom color and shine + * + * @param base base color for the image + * @param shine the custom shine property + * @param resource the file path to the image + * @return The appearance with custom color and shine. + */ private static Appearance simpleAlpha(Color base, float shine, String resource) { return new Appearance( base, @@ -69,6 +91,12 @@ public class DefaultAppearance { private static HashMap plastics = new HashMap(); + /** + * gets the appearance correspondent to the plastic with the given color + * also caches the plastics + * @param c the color of the plastics + * @return The plastic appearance with the given color + */ private static Appearance getPlastic(Color c) { if (!plastics.containsKey(c)) { plastics.put(c, new Appearance(c, .3)); @@ -76,6 +104,12 @@ public class DefaultAppearance { return plastics.get(c); } + /** + * gets the default based on the type of the rocket component + * + * @param c the rocket component + * @return the default appearance for that type of rocket component + */ public static Appearance getDefaultAppearance(RocketComponent c) { if (c instanceof BodyTube) return ESTES_BT; @@ -100,6 +134,12 @@ public class DefaultAppearance { return Appearance.MISSING; } + /** + * gets the default motor texture based on the manufacturer + * returns reusable motor texture as default + * @param m The motor object + * @return The default appearance for the motor + */ public static Appearance getDefaultAppearance(Motor m) { if (m instanceof ThrustCurveMotor) { ThrustCurveMotor tcm = (ThrustCurveMotor) m; diff --git a/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java b/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java index 630cf3639..6c70470ce 100644 --- a/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java +++ b/core/src/net/sf/openrocket/appearance/defaults/ResourceDecalImage.java @@ -8,11 +8,20 @@ import java.io.InputStream; import net.sf.openrocket.appearance.DecalImage; import net.sf.openrocket.util.StateChangeListener; - +/** + * + * Default implementation class of DecalImage + * + */ public class ResourceDecalImage implements DecalImage { + /** File path to the image*/ final String resource; + /** + * main constructor, stores the file path given + * @param resource + */ public ResourceDecalImage(final String resource) { this.resource = resource; } diff --git a/core/src/net/sf/openrocket/communication/UpdateInfo.java b/core/src/net/sf/openrocket/communication/UpdateInfo.java index 78458b812..f4d296e75 100644 --- a/core/src/net/sf/openrocket/communication/UpdateInfo.java +++ b/core/src/net/sf/openrocket/communication/UpdateInfo.java @@ -6,18 +6,30 @@ import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.BuildProperties; import net.sf.openrocket.util.ComparablePair; + /** + * + * class that stores the update information of the application + * + */ public class UpdateInfo { private final String latestVersion; private final ArrayList> updates; - + /** + * loads the default information + */ public UpdateInfo() { this.latestVersion = BuildProperties.getVersion(); this.updates = new ArrayList>(); } + /** + * loads a custom update information into the cache + * @param version String with the version + * @param updates The list of updates contained in the version + */ public UpdateInfo(String version, List> updates) { this.latestVersion = version; this.updates = new ArrayList>(updates); diff --git a/core/src/net/sf/openrocket/communication/UpdateInfoRetriever.java b/core/src/net/sf/openrocket/communication/UpdateInfoRetriever.java index 16d51456b..654ac0a93 100644 --- a/core/src/net/sf/openrocket/communication/UpdateInfoRetriever.java +++ b/core/src/net/sf/openrocket/communication/UpdateInfoRetriever.java @@ -41,10 +41,11 @@ public class UpdateInfoRetriever { * Check whether the update info fetching is still in progress. * * @return true if the communication is still in progress. + * @throws IllegalStateException if {@link #startFetchUpdateInfo()} has not been called */ public boolean isRunning() { if (fetcher == null) { - throw new IllegalStateException("startFetchUpdateInfo() has not been called"); + throw new IllegalStateException("startFetchUpdateInfo() has not been called"); } return fetcher.isAlive(); } @@ -81,43 +82,76 @@ public class UpdateInfoRetriever { */ /* package-private */ static UpdateInfo parseUpdateInput(Reader r) throws IOException { - BufferedReader reader; - if (r instanceof BufferedReader) { - reader = (BufferedReader) r; - } else { - reader = new BufferedReader(r); - } - - + BufferedReader reader = convertToBufferedReader(r); String version = null; + ArrayList> updates = new ArrayList>(); String str = reader.readLine(); while (str != null) { - if (str.matches("^Version: *[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9.-]* *$")) { + if (isHeader(str)) { version = str.substring(8).trim(); - } else if (str.matches("^[0-9]+:\\p{Print}+$")) { - int index = str.indexOf(':'); - int value = Integer.parseInt(str.substring(0, index)); - String desc = str.substring(index + 1).trim(); - if (!desc.equals("")) { - updates.add(new ComparablePair(value, desc)); - } + } else if (isUpdateToken(str)) { + ComparablePair update = parseUpdateToken(str); + if(update != null) + updates.add(update); } - // Ignore anything else str = reader.readLine(); } - if (version != null) { - return new UpdateInfo(version, updates); - } else { + if (version == null) return null; - } + return new UpdateInfo(version, updates); } + /** + * parses a line of a connection content into the information of an update + * @param str the line of the connection + * @return the update information + */ + private static ComparablePair parseUpdateToken(String str){ + int index = str.indexOf(':'); + int value = Integer.parseInt(str.substring(0, index)); + String desc = str.substring(index + 1).trim(); + + if (desc.equals("")) + return null; + return new ComparablePair(value, desc); + } + + /** + * checks if a string contains and update information + * @param str the string itself + * @return true for when the string has an update + * false otherwise + */ + private static boolean isUpdateToken(String str) { + return str.matches("^[0-9]+:\\p{Print}+$"); + } + + /** + * check if the string is formated as an update list header + * @param str the string to be checked + * @return true if str is a header, false otherwise + */ + private static boolean isHeader(String str) { + return str.matches("^Version: *[0-9]+\\.[0-9]+\\.[0-9]+[a-zA-Z0-9.-]* *$"); + } - + /** + * convert, if not yet converted, a Reader into a buffered reader + * @param r the Reader object + * @return the Reader as a BufferedReader Object + */ + private static BufferedReader convertToBufferedReader(Reader r) { + if (r instanceof BufferedReader) + return (BufferedReader) r; + return new BufferedReader(r); + } + + + /** * An asynchronous task that fetches and parses the update info. * @@ -137,11 +171,193 @@ public class UpdateInfoRetriever { } } - + /** + * Establishes a connection with data of previous updates + * @throws IOException + */ private void doConnection() throws IOException { - String url = Communicator.UPDATE_INFO_URL + "?" + Communicator.VERSION_PARAM + "=" - + Communicator.encode(BuildProperties.getVersion()); + HttpURLConnection connection = getConnection(getUrl()); + InputStream is = null; + try { + connection.connect(); + if(!checkConnection(connection)) + return; + if(!checkContentType(connection)) + return; + is = new LimitedInputStream(connection.getInputStream(), Communicator.MAX_INPUT_BYTES); + parseUpdateInput(buildBufferedReader(connection,is)); + } finally { + try { + if (is != null) + is.close(); + connection.disconnect(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * Parses the data received in a buffered reader + * @param reader The reader object + * @throws IOException If anything bad happens + */ + private void parseUpdateInput(BufferedReader reader) throws IOException{ + String version = null; + ArrayList> updates = + new ArrayList>(); + + String line = reader.readLine(); + while (line != null) { + if (isHeader(line)) { + version = parseHeader(line); + } else if (isUpdateInfo(line)) { + updates.add(parseUpdateInfo(line)); + } + line = reader.readLine(); + } + + if (isInvalidVersion(version)) { + log.warn("Invalid version received, ignoring."); + return; + } + + info = new UpdateInfo(version, updates); + log.info("Found update: " + info); + } + + /** + * parses a line into it's version name + * @param line the string of the header + * @return the version in it's right format + */ + private String parseHeader(String line) { + return line.substring(8).trim(); + } + + /** + * parses a line into it's correspondent update information + * @param line the line to be parsed + * @return update information from the line + */ + private ComparablePair parseUpdateInfo(String line){ + String[] split = line.split(":", 2); + int n = Integer.parseInt(split[0]); + return new ComparablePair(n, split[1].trim()); + } + + /** + * checks if a line contains an update information + * @param line the line to be checked + * @return true if the line caontain an update information + * false otherwise + */ + private boolean isUpdateInfo(String line) { + return line.matches("^[0-9]{1,9}:\\P{Cntrl}{1,300}$"); + } + + /** + * checks if a line is a header of an update list + * @param line the line to be checked + * @return true if line is a header, false otherwise + */ + private boolean isHeader(String line) { + return line.matches("^Version:[a-zA-Z0-9._ -]{1,30}$"); + } + + /** + * checks if a String is a valid version + * @param version the String to be checked + * @return true if it's valid, false otherwise + */ + private boolean isInvalidVersion(String version) { + return version == null || version.length() == 0 || + version.equalsIgnoreCase(BuildProperties.getVersion()); + } + + /** + * builds a buffered reader from an open connection and a stream + * @param connection The connection + * @param is The input stream + * @return The Buffered reader created + * @throws IOException + */ + private BufferedReader buildBufferedReader(HttpURLConnection connection, InputStream is) throws IOException { + String encoding = connection.getContentEncoding(); + if (encoding == null || encoding.equals("")) + encoding = "UTF-8"; + return new BufferedReader(new InputStreamReader(is, encoding)); + } + + /** + * check if the content of a connection is valid + * @param connection the connection to be checked + * @return true if the content is valid, false otherwise + */ + private boolean checkContentType(HttpURLConnection connection) { + String contentType = connection.getContentType(); + if (contentType == null || + contentType.toLowerCase(Locale.ENGLISH).indexOf(Communicator.UPDATE_INFO_CONTENT_TYPE) < 0) { + // Unknown response type + log.warn("Unknown Content-type received:" + contentType); + return false; + } + return true; + } + + /** + * check if a connection is responsive and valid + * @param connection the connection to be checked + * @return true if connection is ok, false otherwise + * @throws IOException + */ + private boolean checkConnection(HttpURLConnection connection) throws IOException{ + log.debug("Update response code: " + connection.getResponseCode()); + + if (noUpdatesAvailable(connection)) { + log.info("No updates available"); + info = new UpdateInfo(); + return false; + } + + if (!updateAvailable(connection)) { + // Error communicating with server + log.warn("Unknown server response code: " + connection.getResponseCode()); + return false; + } + return true; + } + + /** + * checks if a connection sent an update available flag + * @param connection the connection to be checked + * @return true if the response was an update available flag + * false otherwise + * @throws IOException if anything goes wrong + */ + private boolean updateAvailable(HttpURLConnection connection) throws IOException { + return connection.getResponseCode() == Communicator.UPDATE_INFO_UPDATE_AVAILABLE; + } + + /** + * checks if a connection sent an update unavailable flag + * @param connection the connection to be checked + * @return true if the response was an no update available flag + * false otherwise + * @throws IOException if anything goes wrong + */ + private boolean noUpdatesAvailable(HttpURLConnection connection) throws IOException { + return connection.getResponseCode() == Communicator.UPDATE_INFO_NO_UPDATE_CODE; + } + + /** + * Builds a connection with the given url + * @param url the url + * @return connection base on the url + * @throws IOException + */ + private HttpURLConnection getConnection(String url) throws IOException{ HttpURLConnection connection = Communicator.connectionSource.getConnection(url); connection.setConnectTimeout(Communicator.CONNECTION_TIMEOUT); @@ -165,80 +381,16 @@ public class UpdateInfoRetriever { connection.setRequestProperty("X-OpenRocket-Locale", Communicator.encode(Locale.getDefault().toString())); connection.setRequestProperty("X-OpenRocket-CPUs", "" + Runtime.getRuntime().availableProcessors()); - - InputStream is = null; - try { - connection.connect(); - - log.debug("Update response code: " + connection.getResponseCode()); - - if (connection.getResponseCode() == Communicator.UPDATE_INFO_NO_UPDATE_CODE) { - // No updates are available - log.info("No updates available"); - info = new UpdateInfo(); - return; - } - - if (connection.getResponseCode() != Communicator.UPDATE_INFO_UPDATE_AVAILABLE) { - // Error communicating with server - log.warn("Unknown server response code: " + connection.getResponseCode()); - return; - } - - String contentType = connection.getContentType(); - if (contentType == null || - contentType.toLowerCase(Locale.ENGLISH).indexOf(Communicator.UPDATE_INFO_CONTENT_TYPE) < 0) { - // Unknown response type - log.warn("Unknown Content-type received:" + contentType); - return; - } - - // Update is available, parse input - is = connection.getInputStream(); - is = new LimitedInputStream(is, Communicator.MAX_INPUT_BYTES); - String encoding = connection.getContentEncoding(); - if (encoding == null || encoding.equals("")) - encoding = "UTF-8"; - BufferedReader reader = new BufferedReader(new InputStreamReader(is, encoding)); - - String version = null; - ArrayList> updates = - new ArrayList>(); - - String line = reader.readLine(); - while (line != null) { - - if (line.matches("^Version:[a-zA-Z0-9._ -]{1,30}$")) { - version = line.substring(8).trim(); - } else if (line.matches("^[0-9]{1,9}:\\P{Cntrl}{1,300}$")) { - String[] split = line.split(":", 2); - int n = Integer.parseInt(split[0]); - updates.add(new ComparablePair(n, split[1].trim())); - } - // Ignore line otherwise - line = reader.readLine(); - } - - // Check version input - if (version == null || version.length() == 0 || - version.equalsIgnoreCase(BuildProperties.getVersion())) { - // Invalid response - log.warn("Invalid version received, ignoring."); - return; - } - - - info = new UpdateInfo(version, updates); - log.info("Found update: " + info); - } finally { - try { - if (is != null) - is.close(); - connection.disconnect(); - } catch (Exception e) { - e.printStackTrace(); - } - } + return connection; + } + + /** + * builds the default url for fetching updates + * @return the string with an url for fethcing updates + */ + private String getUrl() { + return Communicator.UPDATE_INFO_URL + "?" + Communicator.VERSION_PARAM + "=" + + Communicator.encode(BuildProperties.getVersion()); } } } diff --git a/core/src/net/sf/openrocket/database/AsynchronousDatabaseLoader.java b/core/src/net/sf/openrocket/database/AsynchronousDatabaseLoader.java index 71bda4757..a8aed6f5c 100644 --- a/core/src/net/sf/openrocket/database/AsynchronousDatabaseLoader.java +++ b/core/src/net/sf/openrocket/database/AsynchronousDatabaseLoader.java @@ -43,7 +43,7 @@ public abstract class AsynchronousDatabaseLoader { /** - * Return whether loading the database has ended. + * @return whether loading the database has ended. */ public boolean isLoaded() { return endedLoading; @@ -86,10 +86,27 @@ public abstract class AsynchronousDatabaseLoader { } } - + /** + * + */ private void doLoad() { // Pause for indicated startup time + pauseForStartupTime(); + + loadDatabase(); + + synchronized (this) { + endedLoading = true; + this.notifyAll(); + } + } + + + /** + * waits the startup time before loading the database + */ + private void pauseForStartupTime() { long startLoading = System.currentTimeMillis() + startupDelay; while (!inUse && System.currentTimeMillis() < startLoading) { synchronized (this) { @@ -99,16 +116,11 @@ public abstract class AsynchronousDatabaseLoader { } } } - - loadDatabase(); - - synchronized (this) { - endedLoading = true; - this.notifyAll(); - } } - + /** + * method that actually load the database + */ protected abstract void loadDatabase(); diff --git a/core/src/net/sf/openrocket/database/ComponentPresetDao.java b/core/src/net/sf/openrocket/database/ComponentPresetDao.java index a27a7f5d4..aaa66bf1d 100644 --- a/core/src/net/sf/openrocket/database/ComponentPresetDao.java +++ b/core/src/net/sf/openrocket/database/ComponentPresetDao.java @@ -6,10 +6,23 @@ import net.sf.openrocket.preset.ComponentPreset; public interface ComponentPresetDao { + /** + * return a list all components + * @return list of all components + */ public List listAll(); + /** + * insert a component preset into a database + * @param preset the component to be inserted into the database + */ public void insert( ComponentPreset preset ); + /** + * return all components preset matching the given type + * @param type the searched type + * @return the list of components matching the type + */ public List listForType( ComponentPreset.Type type ); /** @@ -21,13 +34,35 @@ public interface ComponentPresetDao { * @return */ public List listForType( ComponentPreset.Type type, boolean favorite ); - + + /** + * Returns a list of components presets of multiple types + * @param type the types to be searched for + * @return + */ public List listForTypes( ComponentPreset.Type ... type ); + /** + * Returns a list of components preset of each type in the list + * @param types the list of types to be searched for + * @return + */ public List listForTypes( List types ); + /** + * set or reset a component preset as favorite + * @param preset the preset to be set as favorite + * @param type the type of the preset + * @param favorite true to set, false to reset as favorite + */ public void setFavorite( ComponentPreset preset, ComponentPreset.Type type, boolean favorite ); + /** + * returns a list of components preset based on manufacturer and part number + * @param manufacturer the manufacturer to be searched for + * @param partNo the part number of the component + * @return the resulting list of the search + */ public List find( String manufacturer, String partNo ); } \ No newline at end of file diff --git a/core/src/net/sf/openrocket/database/Database.java b/core/src/net/sf/openrocket/database/Database.java index 3f16e818a..df513ea21 100644 --- a/core/src/net/sf/openrocket/database/Database.java +++ b/core/src/net/sf/openrocket/database/Database.java @@ -19,6 +19,7 @@ import net.sf.openrocket.database.DatabaseListener; */ public class Database> extends AbstractSet { + /** the list that contains the data from the database itself*/ protected final List list = new ArrayList(); private final ArrayList> listeners = new ArrayList>(); @@ -33,6 +34,10 @@ public class Database> extends AbstractSet { return list.size(); } + /** + * {@inheritDoc} + * fires add event + */ @Override public boolean add(T element) { int index; @@ -71,17 +76,27 @@ public class Database> extends AbstractSet { return list.indexOf(m); } - + /** + * adds a listener for database changes + * @param listener the listener + */ public void addDatabaseListener(DatabaseListener listener) { listeners.add(listener); } + /** + * removes a listener from the list os listeners + * @param listener + */ public void removeChangeListener(DatabaseListener listener) { listeners.remove(listener); } - + /** + * wake up call for database listeners for when elements are added + * @param element the element added + */ @SuppressWarnings("unchecked") protected void fireAddEvent(T element) { Object[] array = listeners.toArray(); @@ -90,6 +105,10 @@ public class Database> extends AbstractSet { } } + /** + * wake up call for database listeners when elements are removed + * @param element the removed element + */ @SuppressWarnings("unchecked") protected void fireRemoveEvent(T element) { Object[] array = listeners.toArray(); @@ -98,10 +117,6 @@ public class Database> extends AbstractSet { } } - - - - /** * Iterator class implementation that fires changes if remove() is called. */ @@ -120,6 +135,10 @@ public class Database> extends AbstractSet { return current; } + /** + * {@inheritDoc} + * fires remove event + */ @Override public void remove() { iterator.remove(); diff --git a/core/src/net/sf/openrocket/database/DatabaseListener.java b/core/src/net/sf/openrocket/database/DatabaseListener.java index a24b2ddeb..54438f163 100644 --- a/core/src/net/sf/openrocket/database/DatabaseListener.java +++ b/core/src/net/sf/openrocket/database/DatabaseListener.java @@ -1,9 +1,24 @@ package net.sf.openrocket.database; +/** + * interface defining listeners for database + * + * @param type stored in the database + */ public interface DatabaseListener> { + /** + * action for when elements are added + * @param element the element added + * @param source the database of which the element was added + */ public void elementAdded(T element, Database source); + /** + * action for when elements are removed + * @param element the removed element + * @param source the database on which the element was removed + */ public void elementRemoved(T element, Database source); } diff --git a/core/src/net/sf/openrocket/database/Databases.java b/core/src/net/sf/openrocket/database/Databases.java index ffe3628eb..d28e92ac0 100644 --- a/core/src/net/sf/openrocket/database/Databases.java +++ b/core/src/net/sf/openrocket/database/Databases.java @@ -117,7 +117,13 @@ public class Databases { BULK_MATERIAL.addDatabaseListener(listener); } - + /** + * builds a new material based on the parameters given + * @param type The type of material + * @param baseName the name of material + * @param density density + * @return a new onejct withe the material data + */ private static Material newMaterial(Type type, String baseName, double density) { String name = trans.get("material", baseName); return Material.newMaterial(type, name, density, false); @@ -145,21 +151,7 @@ public class Databases { * @return the material, or null if not found. */ public static Material findMaterial(Material.Type type, String baseName) { - Database db; - switch (type) { - case BULK: - db = BULK_MATERIAL; - break; - case SURFACE: - db = SURFACE_MATERIAL; - break; - case LINE: - db = LINE_MATERIAL; - break; - default: - throw new IllegalArgumentException("Illegal material type: " + type); - } - + Database db = getDatabase(type); String name = trans.get("material", baseName); for (Material m : db) { @@ -170,6 +162,24 @@ public class Databases { return null; } + /** + * gets the specific database with the given type + * @param type the desired type + * @return the database of the type given + */ + private static Database getDatabase(Material.Type type){ + switch (type) { + case BULK: + return BULK_MATERIAL; + case SURFACE: + return SURFACE_MATERIAL; + case LINE: + return LINE_MATERIAL; + default: + throw new IllegalArgumentException("Illegal material type: " + type); + } + } + /** * Find a material from the database or return a new user defined material if the specified @@ -184,21 +194,7 @@ public class Databases { * @return the material object from the database or a new material. */ public static Material findMaterial(Material.Type type, String baseName, double density) { - Database db; - switch (type) { - case BULK: - db = BULK_MATERIAL; - break; - case SURFACE: - db = SURFACE_MATERIAL; - break; - case LINE: - db = LINE_MATERIAL; - break; - default: - throw new IllegalArgumentException("Illegal material type: " + type); - } - + Database db = getDatabase(type); String name = trans.get("material", baseName); for (Material m : db) { diff --git a/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java b/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java index bbdc628b1..72da33d01 100644 --- a/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java +++ b/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java @@ -45,31 +45,128 @@ public class ThrustCurveMotorSet implements Comparable { private Motor.Type type = Motor.Type.UNKNOWN; - + /** + * adds a motor into the set, + * uses digest and designation to determinate if a motor is present or not + * @param motor the motor to be added + */ public void addMotor(ThrustCurveMotor motor) { - // Check for first insertion - if (motors.isEmpty()) { - manufacturer = motor.getManufacturer(); - designation = motor.getDesignation(); - simplifiedDesignation = simplifyDesignation(designation); - diameter = motor.getDiameter(); - length = motor.getLength(); - totalImpulse = Math.round((motor.getTotalImpulseEstimate())); + checkFirstInsertion(motor); + verifyMotor(motor); + updateType(motor); + checkChangeSimplifiedDesignation(motor); + addStandardDelay(motor); + if(!checkMotorOverwrite(motor)){ + motors.add(motor); + digestMap.put(motor, motor.getDigest()); + Collections.sort(motors, comparator); + } + } + + /** + * checks whether a motor is present, overwriting it + * @param motor the motor to be checked + * @return if there was an overwrite or not + */ + private boolean checkMotorOverwrite(ThrustCurveMotor motor) { + // Check whether to add as new motor or overwrite existing + final String digest = motor.getDigest(); + for (int index = 0; index < motors.size(); index++) { + Motor m = motors.get(index); + + if (isMotorPresent(motor, digest, m)) { + String newCmt = getFormattedDescription(motor); + String oldCmt = getFormattedDescription(m); + if (isNewDescriptionIrrelevant(newCmt, oldCmt)) { + return true; + } else if (oldCmt.length() == 0) { + replaceMotor(motor, digest, index); + return true; + } + } } - - // Verify that the motor can be added - if (!matches(motor)) { - throw new IllegalArgumentException("Motor does not match the set:" + - " manufacturer=" + manufacturer + - " designation=" + designation + - " diameter=" + diameter + - " length=" + length + - " set_size=" + motors.size() + - " motor=" + motor); + return false; + } + + + /** + * get a description from a motor + * @param motor the motor + * @return the description of the motor + */ + private String getFormattedDescription(Motor motor) { + return motor.getDescription().replaceAll("\\s+", " ").trim(); + } + + + /** + * checks if a motor is in the maps + * @param motor the motor to be checked + * @param digest the digest of the motor + * @param m the current motor being checked with + * @return wheter the motor is or no + */ + private boolean isMotorPresent(ThrustCurveMotor motor, final String digest, Motor m) { + return digest.equals(digestMap.get(m)) && + motor.getDesignation().equals(m.getDesignation()); + } + + + /** + * replace a motor into the given index + * @param motor + * @param digest + * @param index + */ + private void replaceMotor(ThrustCurveMotor motor, final String digest, int index) { + motors.set(index, motor); + digestMap.put(motor, digest); + } + + + + + /** + * checks if the new commit message is empty or equals to the old commit + * @param newCmt the new commit message + * @param oldCmt the old commit message + * @return whether the new commit is empty or equals to the old commit + */ + private boolean isNewDescriptionIrrelevant(String newCmt, String oldCmt) { + return newCmt.length() == 0 || newCmt.equals(oldCmt); + } + + /** + * adds the standard delay if aplicable + * @param motor the motor to be considered + */ + private void addStandardDelay(ThrustCurveMotor motor) { + for (double d : motor.getStandardDelays()) { + d = Math.rint(d); + if (!delays.contains(d)) { + delays.add(d); + } } - - // Update the type if now known + Collections.sort(delays); + } + + /** + * checks if simplified designation should be changed with the given motor + * @param motor the motor to be checked with + */ + private void checkChangeSimplifiedDesignation(ThrustCurveMotor motor) { + if (!designation.equalsIgnoreCase(motor.getDesignation().trim())) { + designation = simplifiedDesignation; + } + } + + /** + * checks if the cached type should be changed with the given motor + * if it's hybrid, delays will be added + * @param motor the motor to be checked with + */ + private void updateType(ThrustCurveMotor motor) { if (type == Motor.Type.UNKNOWN) { type = motor.getMotorType(); // Add "Plugged" option if hybrid @@ -79,56 +176,45 @@ public class ThrustCurveMotorSet implements Comparable { } } } - - // Change the simplified designation if necessary - if (!designation.equalsIgnoreCase(motor.getDesignation().trim())) { - designation = simplifiedDesignation; + } + + /** + * verifies if a motor is valid + * @param motor + */ + private void verifyMotor(ThrustCurveMotor motor) { + if (!matches(motor)) { + throw new IllegalArgumentException("Motor does not match the set:" + + " manufacturer=" + manufacturer + + " designation=" + designation + + " diameter=" + diameter + + " length=" + length + + " set_size=" + motors.size() + + " motor=" + motor); } - - // Add the standard delays - for (double d : motor.getStandardDelays()) { - d = Math.rint(d); - if (!delays.contains(d)) { - delays.add(d); - } + } + + /** + * check if the given motor is the first one, and sets attributes according to it + * @param motor + */ + private void checkFirstInsertion(ThrustCurveMotor motor) { + if (motors.isEmpty()) { + manufacturer = motor.getManufacturer(); + designation = motor.getDesignation(); + simplifiedDesignation = simplifyDesignation(designation); + diameter = motor.getDiameter(); + length = motor.getLength(); + totalImpulse = Math.round((motor.getTotalImpulseEstimate())); } - Collections.sort(delays); - - - // Check whether to add as new motor or overwrite existing - final String digest = motor.getDigest(); - for (int index = 0; index < motors.size(); index++) { - Motor m = motors.get(index); - - if (digest.equals(digestMap.get(m)) && - motor.getDesignation().equals(m.getDesignation())) { - - // Match found, check which one to keep (or both) based on comment - String newCmt = motor.getDescription().replaceAll("\\s+", " ").trim(); - String oldCmt = m.getDescription().replaceAll("\\s+", " ").trim(); - - if (newCmt.length() == 0 || newCmt.equals(oldCmt)) { - // Do not replace and do not add - return; - } else if (oldCmt.length() == 0) { - // Replace existing motor - motors.set(index, motor); - digestMap.put(motor, digest); - return; - } - // else continue search and add both - - } - } - - // Motor not present, add it - motors.add(motor); - digestMap.put(motor, digest); - Collections.sort(motors, comparator); - } - + /** + * Checks if a motor can be added with the set + * A set contains motors of same manufacturer, diameter, length and type + * @param m the motor to be checked with + * @return if the motor passed the test or not + */ public boolean matches(ThrustCurveMotor m) { if (motors.isEmpty()) return true; @@ -153,12 +239,18 @@ public class ThrustCurveMotorSet implements Comparable { return true; } - + /** + * returns a new list with the stored motors + * @return list + */ public List getMotors() { return motors.clone(); } - + /** + * + * @return number of motor in the set + */ public int getMotorCount() { return motors.size(); } diff --git a/core/src/net/sf/openrocket/document/Attachment.java b/core/src/net/sf/openrocket/document/Attachment.java index 6ac927495..ec9fd2769 100644 --- a/core/src/net/sf/openrocket/document/Attachment.java +++ b/core/src/net/sf/openrocket/document/Attachment.java @@ -7,19 +7,38 @@ import java.io.InputStream; import net.sf.openrocket.util.AbstractChangeSource; import net.sf.openrocket.util.ChangeSource; +/** + * + * Class handler of documents attachments + * + */ public abstract class Attachment extends AbstractChangeSource implements Comparable, ChangeSource { private final String name; + /** + * default constructor + * @param name the name of attachment + */ public Attachment(String name) { super(); this.name = name; } + /** + * returns the name of attachment + * @return name of attachment + */ public String getName() { return name; } + /** + * returns the stream of bytes representing the attachment + * @return the stream of bytes representing the attachment + * @throws FileNotFoundException + * @throws IOException + */ public abstract InputStream getBytes() throws FileNotFoundException, IOException; @Override diff --git a/core/src/net/sf/openrocket/document/DecalRegistry.java b/core/src/net/sf/openrocket/document/DecalRegistry.java index b96cafba9..dec64c8a2 100644 --- a/core/src/net/sf/openrocket/document/DecalRegistry.java +++ b/core/src/net/sf/openrocket/document/DecalRegistry.java @@ -25,11 +25,20 @@ import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.FileUtils; import net.sf.openrocket.util.StateChangeListener; +/** + * + * Class that handles decal usage registration + * + */ public class DecalRegistry { + /** + * default constructor + */ DecalRegistry() { } + /** the decal usage map*/ private Map registeredDecals = new HashMap(); public DecalImage makeUniqueImage(DecalImage original) { diff --git a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java index d27c07da1..4d481a676 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java @@ -12,16 +12,24 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC private static final Translator trans = Application.getTranslator(); //private static final Logger log = LoggerFactory.getLogger(AxialStage.class); + /** list of separations to be happening*/ protected FlightConfigurableParameterSet separations; - + /** number of stages */ protected int stageNumber; + /** + * default constructor, builds a rocket with zero stages + */ public AxialStage(){ this.separations = new FlightConfigurableParameterSet( new StageSeparationConfiguration()); this.relativePosition = Position.AFTER; this.stageNumber = 0; } + /** + * {@inheritDoc} + * AxialStage will always accept children + */ @Override public boolean allowsChildren() { return true; @@ -33,6 +41,10 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC return trans.get("Stage.Stage"); } + /** + * gets the separation configuration of the rocket + * @return the separation configuration of the rocket + */ public FlightConfigurableParameterSet getSeparationConfigurations() { return separations; } @@ -42,7 +54,10 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC separations.reset(fcid); } - // not strictly accurate, but this should provide an acceptable estimate for total vehicle size + /** + * {@inheritDoc} + * not strictly accurate, but this should provide an acceptable estimate for total vehicle size + */ @Override public Collection getComponentBounds() { Collection bounds = new ArrayList(8); @@ -110,16 +125,28 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC return this.stageNumber; } + /** + * {@inheritDoc} + * axialStage is always after + */ @Override public boolean isAfter(){ return true; } + /** + * returns if the object is a launch stage + * @return if the object is a launch stage + */ public boolean isLaunchStage(){ return ( this instanceof ParallelStage ) ||( getRocket().getBottomCoreStage().equals(this)); } + /** + * sets the stage number + * @param newStageNumber + */ public void setStageNumber(final int newStageNumber) { this.stageNumber = newStageNumber; } @@ -138,12 +165,21 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC return buf; } + /** + * method used for debugging separation + * @return a string that represents the debug message of separation + */ public String toDebugSeparation() { StringBuilder buff = new StringBuilder(); buff.append( this.separations.toDebug() ); return buff.toString(); } + /** + * gets the previous stage installed in the rockets + * returns null if this is the first stage + * @return the previous stage in the rocket + */ public AxialStage getPreviousStage() { if( this instanceof ParallelStage ){ return (AxialStage) this.parent; diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 6fda14f90..6f2413d97 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -30,7 +30,11 @@ import net.sf.openrocket.util.SafetyMutex; import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.UniqueID; - +/** + * Master class that defines components of rockets + * almost all hardware from the rocket extends from this abstract class + * + */ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterable { @SuppressWarnings("unused") private static final Logger log = LoggerFactory.getLogger(RocketComponent.class); @@ -41,7 +45,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab //private static final Translator trans = Application.getTranslator(); - /* + /** * Text is suitable to the form * Position relative to: */