Compare commits

...

22 Commits

Author SHA1 Message Date
Marcus Hoffmann 1eeecf8a8b remove javadoc zip files from the repo 2023-11-13 12:05:45 +01:00
Marcus Hoffmann f3cb964d3d remove non-functioning billing implementation
Google Play doesn't allow an app signed with a different certificate to
trigger an IAP.
2023-11-12 19:45:34 +01:00
Marcus Hoffmann 0552254213 update plotter submodule
Changes:
* Remove unused app gradle module
2023-11-12 15:31:33 +01:00
Marcus Hoffmann 726bf6b5d7 Readme: Fix markdown format of license comment link 2023-11-12 15:24:11 +01:00
Marcus Hoffmann 91f9de66e6 merge new upstream version
Include plotter and otto project as git submodules and gradle modules
into the build.
2023-11-12 15:19:47 +01:00
Sergey Solovyev ff1b79d9a3 Bump app version 2023-09-18 09:38:06 +02:00
Sergey Solovyev fb0edf5b13 Revert "Request new POST_NOTIFICATIONS permissions"
This reverts commit 308b5504bd.
2023-09-18 09:37:07 +02:00
Sergey Solovyev 308b5504bd Request new POST_NOTIFICATIONS permissions 2023-09-17 13:29:19 +02:00
Sergey Solovyev 35408e42b3 Clean up proguard rules and remove Plotter's Check from the release builds 2023-09-17 13:06:11 +02:00
Sergey Solovyev e676502d61 Fix crash in Edit history item dialog 2023-09-17 13:01:14 +02:00
Marcus b93ee7812f
link to archive.org version of license comment 2022-08-04 20:54:25 +02:00
Marcus 1200a88fb4
link to original repo, remove gplay bade, mention project status 2022-08-04 20:50:30 +02:00
Marcus 03a243d3b8
Merge pull request #2 from mmahmoudian/add-license-file
add the LICENSE and put together a basic README
2022-08-04 20:00:46 +02:00
Mehrad Mahmoudian bdd0cdbd7e add the LICENSE and put together a basic README 2022-08-04 17:35:11 +03:00
Marcus 5dea292c91
Merge pull request #1 from neuron303/master
Delete ga.xml
2022-08-04 12:08:01 +02:00
neuron303 2976a679b1
Delete ga.xml
Removes unused Google Analytics file to remove F-Droid anti-feature warning
See 32826c8334
2021-08-12 15:40:40 +02:00
Marcus Hoffmann c67dc96d57 fix crash on converter dialogue
This vendors the jscience javax.measure package, extracted from
https://repo1.maven.org/maven2/org/jscience/jscience/4.3.1/jscience-4.3.1-sources.jar

Using this package as a dependency leads to conflicting classes, which
we can't solve from gradle. Instead of repackaging the jar file the
easiest solution seems to be to vendor the sources we need.
2020-03-16 15:52:46 +01:00
Marcus Hoffmann e00b18a0e6 remove unneeded permissions 2020-03-16 13:31:12 +01:00
Marcus Hoffmann 44296836ee bump versioncode 2020-03-16 13:01:08 +01:00
Marcus Hoffmann ddade5e165 remove leftover references to AdView 2020-03-16 13:00:18 +01:00
Marcus Hoffmann 3d9a6858a1 use otto from mavenLocal 2020-03-13 22:45:31 +01:00
Marcus Hoffmann 6fa4bfb05f remove google play dependencies and some jars 2020-03-12 16:57:54 +01:00
115 changed files with 7646 additions and 885 deletions

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "plotter"]
path = plotter
url = https://git.bubu1.eu/Bubu/android-plotter.git
[submodule "otto"]
path = otto
url = https://git.bubu1.eu/Bubu/serso-otto.git

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

47
README.md Normal file
View File

@ -0,0 +1,47 @@
# Calculator++
Scientific calculator with sleek interface and powerful capabilities. This repository contains the version distributed by [F-Droid.org](https://f-droid.org/) and is a slightly modified version of [Sero's](https://github.com/serso/android-calculatorpp) original Calculator++ App. The modifications consist of removing pre-built binaries from the repository as well as removing Google Analytics. All credit besides the before mentioned modifications go to the original author. No further work is planned here from my side.
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid"
height="70">](https://f-droid.org/en/packages/org.solovyev.android.calculator/)
(The original version is also available via [Google Play](https://play.google.com/store/apps/details?id=org.solovyev.android.calculator))
![Demo how the app looks like](https://raw.githubusercontent.com/Bubu/android-calculatorpp/master/assets/intro.png "An image showing three phone screens, each showing one view of the calculator app")
★ Save your time!
* Access additional features from the main screen of the app using gestures. For example, to use «%» slide button «/» up
* You don't need to press «=» anymore - result is calculated automatically
* Copy/paste with a single button press
* App supports both portrait and landscape screen orientations
★ Personalize!
* C++ has two layouts: standard and engineer. Choose one which suits you best either from the initial wizard or from the application settings
* Set theme you like
* Add home screen widget
★ Do calculations without switching between the apps!
Calculator++ can work in a separate window floating over other applications on your phone
★ Calculate percentages, square roots, powers, trigonometric functions!
Calculator has a big variety of built-in functions and supports adding new user-defined functions
★ Plot 2D and 3D graphs!
Several functions can be plotted simultaneously
★ Use powerful mathematical capabilities of the app:
* Do calculations with variables and constants
* Use built-in functions or add your own
* Integrate and differentiate
* Do calculations with fractions and simplify expressions
* Do calculations with complex numbers
## License
This project is licensed under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
The license of this repo was added based on [the comment](https://web.archive.org/web/20210107155932/https://github.com/serso/android-calculatorpp/issues/184#issuecomment-317447082) of the original author (Sergey Solovyev) on 2017-07-24 in which he wrote:
> The project uses Apache License, Version 2.0 (see source files for example). Unfortunately, I didn't have time to declare the licence in a proper way
The LICENSE file of this repo is [what Apache.org provides in text format](https://www.apache.org/licenses/LICENSE-2.0.txt). The only modification made was changing the name from `LICENSE-2.0.txt` to `LICENSE`.

View File

@ -24,8 +24,6 @@ apply plugin: 'com.android.application'
apply plugin: 'signing'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
android {
compileSdk versions.sdk.compile
@ -33,8 +31,8 @@ android {
applicationId "org.solovyev.android.calculator"
minSdkVersion versions.sdk.min
targetSdkVersion versions.sdk.target
versionCode 160
versionName '2.3.2'
versionCode 161
versionName '2.3.3'
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
buildFeatures {
@ -80,21 +78,16 @@ dependencies {
implementation "androidx.preference:preference-ktx:1.2.1"
implementation 'com.google.android.material:material:1.9.0'
implementation ':measure:'
implementation ':square-otto:1.3.9-SNAPSHOT'
kapt ':square-otto:1.3.9-SNAPSHOT'
kapt ':square-otto-compiler:1.3.9-SNAPSHOT'
implementation project(":measure")
implementation project(':otto:otto')
kapt project(':otto:otto')
kapt project(':otto:otto-compiler')
kapt 'com.squareup:javapoet:1.9.0'
implementation project(':plotter:lib')
implementation project(':dragbutton')
implementation(project(':jscl')) {
exclude(module: 'xercesImpl')
}
implementation 'org.solovyev.android:checkout:1.3.1'
implementation platform('com.google.firebase:firebase-bom:32.2.3')
implementation "com.google.firebase:firebase-crashlytics"
implementation "com.google.firebase:firebase-analytics"
implementation 'com.google.android.gms:play-services-ads:22.4.0'
implementation 'com.google.guava:guava:32.1.2-android'
implementation('org.simpleframework:simple-xml:2.7.1') {
exclude(module: 'stax')
@ -112,7 +105,6 @@ dependencies {
testImplementation 'org.mockito:mockito-core:5.3.1'
testImplementation 'org.robolectric:robolectric:4.10.3'
testImplementation 'org.skyscreamer:jsonassert:1.5.0'
testImplementation(name: 'org.apache.http.legacy', ext: 'jar')
androidTestImplementation 'androidx.annotation:annotation:1.7.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'

View File

@ -1,29 +0,0 @@
{
"project_info": {
"project_number": "256354490244",
"project_id": "calculatorpp-86d8a",
"storage_bucket": "calculatorpp-86d8a.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:256354490244:android:4674f70d035e4bbdb5efd1",
"android_client_info": {
"package_name": "org.solovyev.android.calculator"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyDmabRGhOstItse_rveL5ReDooqfK2hDHo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -63,8 +63,6 @@
-dontwarn jscl.mathml.**
-dontwarn com.google.common.**
-dontwarn com.google.ads.**
-dontwarn com.sun.org.apache.xerces.internal.impl.dv.util.Base64
-dontwarn com.actionbarsherlock.BuildConfig
-dontwarn com.google.android.gms.internal.**
-dontwarn com.google.android.gms.common.internal.**
-dontwarn com.google.android.gms.common.GooglePlayServicesUtil
@ -73,16 +71,6 @@
-dontwarn com.squareup.leakcanary.**
-keep class org.simpleframework.xml.** { *; }
-keep class * implements org.solovyev.android.calculator.model.MathPersistenceEntity
-keep class * implements org.solovyev.android.calculator.MathEntityPersistenceContainer
# Allow obfuscation of android.support.v7.internal.view.menu.**
# to avoid problem on Samsung 4.2.2 devices with appcompat v21
# see https://code.google.com/p/android/issues/detail?id=78377
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class !android.support.v7.internal.view.menu.MenuBuilder, !android.support.v7.internal.view.menu.SubMenuBuilder, android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
## JAVAX UNITS
@ -106,45 +94,8 @@
public static *;
}
## ACRA
# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode {
*;
}
-keepnames class org.acra.sender.HttpSender$** {
*;
}
-keepnames class org.acra.ReportField {
*;
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter {
public void addCustomData(java.lang.String,java.lang.String);
public void putCustomData(java.lang.String,java.lang.String);
public void removeCustomData(java.lang.String);
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter {
public void handleSilentException(java.lang.Throwable);
}
## BUTTERKNIFE
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
-assumenosideeffects class org.solovyev.android.plotter.Check {
public static *;
}
## OTTO BUS

View File

@ -2,10 +2,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- for onscreen -->
@ -26,10 +22,6 @@
android:theme="@style/Cpp.Theme.Material"
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-9736972200639245~6870320906"/>
<activity
android:exported="true"
android:name=".CalculatorActivity"

View File

@ -1,146 +0,0 @@
package org.solovyev.android.calculator;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.LoadAdError;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class AdView extends FrameLayout {
@Nullable
private com.google.android.gms.ads.AdView admobView;
@Nullable
private AdView.AdViewListener admobListener;
public AdView(Context context) {
super(context);
init();
}
public AdView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AdView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setVisibility(GONE);
setId(R.id.cpp_ad);
}
public void destroy() {
destroyAdmobView();
}
private void destroyAdmobView() {
if (admobView != null) {
admobView.destroy();
admobView.setAdListener(null);
admobView = null;
}
if (admobListener != null) {
admobListener.destroy();
admobListener = null;
}
}
public void pause() {
if (admobView != null) {
admobView.pause();
}
}
public void resume() {
if (admobView != null) {
admobView.resume();
}
}
public void show() {
if (admobView != null) {
return;
}
admobView = addAdmobView();
admobListener = new AdView.AdViewListener(this);
admobView.setAdListener(admobListener);
final AdRequest.Builder b = new AdRequest.Builder();
admobView.loadAd(b.build());
}
@Nonnull
private com.google.android.gms.ads.AdView addAdmobView() {
final com.google.android.gms.ads.AdView v = new com.google.android.gms.ads.AdView(getContext());
v.setVisibility(GONE);
v.setAdSize(AdSize.SMART_BANNER);
v.setAdUnitId(getResources().getString(R.string.admob));
final LayoutParams lp = new LayoutParams(MATCH_PARENT, WRAP_CONTENT);
lp.gravity = Gravity.CENTER;
addView(v, lp);
return v;
}
public void hide() {
if (admobView == null) {
return;
}
setVisibility(GONE);
admobView.setVisibility(View.GONE);
admobView.pause();
destroyAdmobView();
}
private static class AdViewListener extends AdListener {
@Nullable
private AdView adView;
public AdViewListener(@Nonnull AdView adView) {
this.adView = adView;
}
void destroy() {
adView = null;
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
if (adView != null) {
adView.hide();
adView = null;
}
}
@Override
public void onAdLoaded() {
if (adView != null) {
final com.google.android.gms.ads.AdView admobView = adView.admobView;
if (admobView != null) {
admobView.setVisibility(View.VISIBLE);
}
adView.setVisibility(VISIBLE);
adView = null;
}
}
}
}

View File

@ -1,6 +1,5 @@
package org.solovyev.android.calculator;
import dagger.Component;
import org.solovyev.android.calculator.converter.ConverterFragment;
import org.solovyev.android.calculator.errors.FixableErrorFragment;
import org.solovyev.android.calculator.errors.FixableErrorsActivity;
@ -20,7 +19,6 @@ import org.solovyev.android.calculator.plot.PlotEditFunctionFragment;
import org.solovyev.android.calculator.plot.PlotFunctionsFragment;
import org.solovyev.android.calculator.preferences.PreferencesActivity;
import org.solovyev.android.calculator.preferences.PreferencesFragment;
import org.solovyev.android.calculator.preferences.PurchaseDialogActivity;
import org.solovyev.android.calculator.variables.EditVariableFragment;
import org.solovyev.android.calculator.variables.VariablesFragment;
import org.solovyev.android.calculator.view.Tabs;
@ -31,6 +29,8 @@ import org.solovyev.android.calculator.wizard.WizardFragment;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
@ -54,7 +54,6 @@ public interface AppComponent {
void inject(WidgetReceiver receiver);
void inject(DisplayFragment fragment);
void inject(KeyboardFragment fragment);
void inject(PurchaseDialogActivity activity);
void inject(PreferencesActivity activity);
void inject(BaseKeyboardUi ui);
void inject(FloatingCalculatorView view);

View File

@ -7,19 +7,15 @@ import android.graphics.Typeface;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import android.util.Log;
import com.squareup.otto.Bus;
import androidx.annotation.NonNull;
import com.squareup.otto.Bus;
import com.squareup.otto.GeneratedHandlerFinder;
import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.calculator.wizard.CalculatorWizards;
import org.solovyev.android.checkout.Billing;
import org.solovyev.android.checkout.Checkout;
import org.solovyev.android.checkout.Inventory;
import org.solovyev.android.checkout.RobotmediaDatabase;
import org.solovyev.android.checkout.RobotmediaInventory;
import org.solovyev.android.plotter.Plot;
import org.solovyev.android.plotter.Plotter;
import org.solovyev.android.wizard.Wizards;
@ -31,7 +27,6 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Named;
import javax.inject.Singleton;
@ -182,28 +177,6 @@ public class AppModule {
return JsclMathEngine.getInstance();
}
@Provides
@Singleton
Billing provideBilling() {
return new Billing(application, new Billing.DefaultConfiguration() {
@Nonnull
@Override
public String getPublicKey() {
return CalculatorSecurity.getPK();
}
@Nullable
@Override
public Inventory getFallbackInventory(@Nonnull Checkout checkout, @Nonnull Executor onLoadExecutor) {
if (RobotmediaDatabase.exists(application)) {
return new RobotmediaInventory(checkout, onLoadExecutor);
} else {
return null;
}
}
});
}
@Singleton
@Provides
Typeface provideTypeface() {

View File

@ -27,7 +27,6 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.calculator.language.Language;
import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.calculator.view.Tabs;
@ -48,8 +47,6 @@ public abstract class BaseActivity extends AppCompatActivity implements SharedPr
@Inject
Calculator calculator;
@Inject
Lazy<Ga> ga;
@Inject
Typeface typeface;
ViewGroup mainView;
@Nullable

View File

@ -16,7 +16,6 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import com.google.android.material.textfield.TextInputLayout;
import org.solovyev.android.calculator.ga.Ga;
import javax.inject.Inject;
@ -27,8 +26,6 @@ public abstract class BaseDialogFragment extends DialogFragment implements View.
@Inject
protected SharedPreferences preferences;
@Inject
Ga ga;
@Inject
Typeface typeface;
@Nullable
private Button positiveButton;

View File

@ -8,7 +8,6 @@ import androidx.annotation.NonNull;
import android.view.*;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import org.solovyev.android.calculator.ads.AdUi;
import org.solovyev.android.plotter.Check;
import javax.annotation.Nonnull;
@ -21,8 +20,6 @@ public abstract class BaseFragment extends Fragment {
private final int layout;
@Inject
AdUi adUi;
@Inject
public Typeface typeface;
protected BaseFragment(@LayoutRes int layout) {
@ -31,13 +28,13 @@ public abstract class BaseFragment extends Fragment {
@Nonnull
public static MenuItem addMenu(@Nonnull ContextMenu menu, @StringRes int label,
@Nonnull MenuItem.OnMenuItemClickListener listener) {
@Nonnull MenuItem.OnMenuItemClickListener listener) {
return menu.add(NONE, label, NONE, label).setOnMenuItemClickListener(listener);
}
@NonNull
public static <P extends Parcelable> P getParcelable(@NonNull Bundle bundle,
@NonNull String key) {
@NonNull String key) {
final P parcelable = bundle.getParcelable(key);
Check.isNotNull(parcelable);
return parcelable;
@ -47,7 +44,6 @@ public abstract class BaseFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inject(cast(getActivity().getApplication()).getComponent());
adUi.onCreate();
}
protected void inject(@Nonnull AppComponent component) {
@ -56,34 +52,9 @@ public abstract class BaseFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle savedInstanceState) {
final View view = inflater.inflate(layout, container, false);
adUi.onCreateView(view);
BaseActivity.fixFonts(view, typeface);
return view;
}
@Override
public void onResume() {
super.onResume();
adUi.onResume();
}
@Override
public void onPause() {
adUi.onPause();
super.onPause();
}
@Override
public void onDestroyView() {
adUi.onDestroyView();
super.onDestroyView();
}
@Override
public void onDestroy() {
adUi.onDestroy();
super.onDestroy();
}
}

View File

@ -33,7 +33,6 @@ import android.util.TimingLogger;
import com.squareup.otto.Bus;
import org.solovyev.android.calculator.floating.FloatingCalculatorActivity;
import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.language.Language;
import org.solovyev.android.calculator.language.Languages;
@ -50,27 +49,6 @@ import jscl.MathEngine;
public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener {
// delayed GA reporting in order to avoid initialization of GA on the main
// application thread and to postpone it as much as possible
private class GaInitializer extends AsyncTask<Void, Void, Ga> {
@NonNull
private final SharedPreferences prefs;
GaInitializer(@NonNull SharedPreferences prefs) {
this.prefs = prefs;
}
@Override
protected Ga doInBackground(Void... params) {
return ga.get();
}
@Override
protected void onPostExecute(@NonNull Ga ga) {
ga.reportInitially(prefs);
}
}
@Inject
@Named(AppModule.THREAD_INIT)
Executor initThread;
@ -114,9 +92,6 @@ public class CalculatorApplication extends android.app.Application implements Sh
@Inject
ActivityLauncher launcher;
@Inject
Lazy<Ga> ga;
@Nonnull
private final TimingLogger timer = new TimingLogger("App", "onCreate");
@ -169,7 +144,6 @@ public class CalculatorApplication extends android.app.Application implements Sh
warmUpEngine();
}
});
new GaInitializer(prefs).executeOnExecutor(initThread);
}
private void warmUpEngine() {

View File

@ -35,7 +35,6 @@ import com.squareup.otto.Subscribe;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.buttons.CppSpecialButton;
import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.memory.Memory;
@ -70,8 +69,6 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
@Inject
Engine engine;
@Inject
Lazy<Ga> ga;
@Inject
Lazy<Clipboard> clipboard;
@Inject
ActivityLauncher launcher;
@ -112,13 +109,11 @@ public class Keyboard implements SharedPreferences.OnSharedPreferenceChangeListe
final char glyph = text.charAt(0);
final CppSpecialButton button = CppSpecialButton.getByGlyph(glyph);
if (button != null) {
ga.get().onButtonPressed(button.action);
handleSpecialAction(button);
return true;
}
}
ga.get().onButtonPressed(text);
if (!processSpecialAction(text)) {
processText(prepareText(text));
}

View File

@ -1,113 +0,0 @@
package org.solovyev.android.calculator.ads;
import static org.solovyev.android.checkout.ProductTypes.IN_APP;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import android.view.View;
import org.solovyev.android.calculator.AdView;
import org.solovyev.android.calculator.R;
import org.solovyev.android.checkout.CppCheckout;
import org.solovyev.android.checkout.Inventory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
public class AdUi {
@NonNull
private final CppCheckout checkout;
@NonNull
private final Handler handler;
@Nullable
AdView adView;
@Nullable
private Boolean adFree = null;
@Inject
public AdUi(@NonNull CppCheckout checkout, @NonNull Handler handler) {
this.checkout = checkout;
this.handler = handler;
}
public void onCreate() {
checkout.start();
}
public void onResume() {
if (adView == null) {
return;
}
adView.resume();
if (adFree != null) {
updateAdView();
} else {
checkout.loadInventory(Inventory.Request.create().loadAllPurchases(),
onMainThread(new Inventory.Callback() {
@Override
public void onLoaded(@Nonnull Inventory.Products products) {
adFree = products.get(IN_APP).isPurchased("ad_free");
updateAdView();
}
}));
}
}
private void updateAdView() {
if (adFree == null || adView == null) {
return;
}
if (adFree) {
adView.hide();
} else {
adView.show();
}
}
@Nonnull
private Inventory.Callback onMainThread(@Nonnull final Inventory.Callback callback) {
return new Inventory.Callback() {
@Override
public void onLoaded(@Nonnull final Inventory.Products products) {
if (handler.getLooper() == Looper.myLooper()) {
callback.onLoaded(products);
return;
}
handler.post(new Runnable() {
@Override
public void run() {
callback.onLoaded(products);
}
});
}
};
}
public void onCreateView(@NonNull View view) {
adView = view.findViewById(R.id.cpp_ad);
}
public void onPause() {
adFree = null;
if (adView != null) {
adView.pause();
}
}
public void onDestroyView() {
if (adView == null) {
return;
}
adView.destroy();
adView = null;
}
public void onDestroy() {
checkout.stop();
}
}

View File

@ -36,7 +36,6 @@ import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.ga.Ga;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -59,8 +58,6 @@ public class FloatingCalculatorService extends Service implements FloatingViewLi
@Inject
Display display;
@Inject
Ga ga;
@Inject
SharedPreferences preferences;
public static void show(@Nonnull Context context) {
@ -139,7 +136,6 @@ public class FloatingCalculatorService extends Service implements FloatingViewLi
if (isShowWindowIntent(intent)) {
hideNotification();
createView();
ga.onFloatingCalculatorOpened();
} else if (isShowNotificationIntent(intent)) {
showNotification();
}

View File

@ -1,65 +0,0 @@
package org.solovyev.android.calculator.ga;
import android.app.Application;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import com.google.firebase.analytics.FirebaseAnalytics;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.solovyev.android.calculator.Preferences;
@Singleton
public final class Ga implements SharedPreferences.OnSharedPreferenceChangeListener {
@Nonnull
private final FirebaseAnalytics analytics;
@Inject
public Ga(@Nonnull Application application, @Nonnull SharedPreferences preferences) {
analytics = FirebaseAnalytics.getInstance(application);
preferences.registerOnSharedPreferenceChangeListener(this);
}
private void reportLayout(@Nonnull Preferences.Gui.Mode mode) {
final Bundle params = new Bundle();
params.putString("name", mode.name());
analytics.logEvent("layout", params);
}
private void reportTheme(@Nonnull Preferences.Gui.Theme theme) {
final Bundle params = new Bundle();
params.putString("name", theme.name());
analytics.logEvent("theme", params);
}
public void onButtonPressed(@Nullable String text) {
if (TextUtils.isEmpty(text)) {
return;
}
final Bundle params = new Bundle();
params.putString("text", text);
analytics.logEvent("click", params);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (TextUtils.equals(key, Preferences.Gui.mode.getKey())) {
reportLayout(Preferences.Gui.mode.getPreferenceNoError(preferences));
} else if (TextUtils.equals(key, Preferences.Gui.theme.getKey())) {
reportTheme(Preferences.Gui.theme.getPreferenceNoError(preferences));
}
}
public void reportInitially(@Nonnull SharedPreferences preferences) {
reportLayout(Preferences.Gui.mode.getPreferenceNoError(preferences));
reportTheme(Preferences.Gui.theme.getPreferenceNoError(preferences));
}
public void onFloatingCalculatorOpened() {
analytics.logEvent("floating_calculator_open", null);
}
}

View File

@ -4,19 +4,17 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.annotation.XmlRes;
import android.util.SparseArray;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.checkout.ActivityCheckout;
import org.solovyev.android.checkout.Billing;
import org.solovyev.android.checkout.Checkout;
import javax.annotation.Nonnull;
import javax.inject.Inject;
@ -42,10 +40,6 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
preferenceDefs.append(R.xml.preferences_widget, new PrefDef("screen-widget", R.string.cpp_widget));
}
ActivityCheckout checkout;
@Inject
Billing billing;
@Inject
Languages languages;
@ -84,9 +78,6 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
.add(R.id.main, PreferencesFragment.create(preference))
.commit();
}
checkout = Checkout.forActivity(this, billing);
checkout.start();
}
@Override
@ -95,17 +86,6 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
component.inject(this);
}
@Override
protected void onDestroy() {
checkout.stop();
super.onDestroy();
}
@Nonnull
ActivityCheckout getCheckout() {
return checkout;
}
static class PrefDef {
@Nonnull
public final String id;

View File

@ -5,33 +5,25 @@ import static org.solovyev.android.calculator.Engine.Preferences.angleUnitName;
import static org.solovyev.android.calculator.Engine.Preferences.numeralBaseName;
import static org.solovyev.android.calculator.wizard.CalculatorWizards.DEFAULT_WIZARD_FLOW;
import static org.solovyev.android.wizard.WizardUi.startWizard;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceDialogFragmentCompat;
import androidx.preference.PreferenceFragmentCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.NumeralBase;
import org.solovyev.android.calculator.ActivityLauncher;
import org.solovyev.android.calculator.AdView;
import org.solovyev.android.calculator.Engine;
import org.solovyev.android.calculator.Preferences;
import org.solovyev.android.calculator.Preferences.Gui.Theme;
@ -39,21 +31,24 @@ import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.feedback.FeedbackReporter;
import org.solovyev.android.calculator.language.Language;
import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.checkout.BillingRequests;
import org.solovyev.android.checkout.Checkout;
import org.solovyev.android.checkout.ProductTypes;
import org.solovyev.android.checkout.RequestListener;
import org.solovyev.android.prefs.StringPreference;
import org.solovyev.android.wizard.Wizards;
import org.solovyev.common.text.CharacterMapper;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.NumeralBase;
public class PreferencesFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@Nonnull
private static String ARG_PREFERENCES = "preferences";
@Nullable
private AdView adView;
@Inject
SharedPreferences preferences;
@Inject
@ -104,7 +99,9 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Sha
}
}
/** @noinspection deprecation*/
/**
* @noinspection deprecation
*/
@Override
public void onDisplayPreferenceDialog(@NonNull Preference preference) {
String fragmentTag = "fragment:" + preference.getKey();
@ -129,7 +126,6 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Sha
prepareIntroduction();
prepareReportBug();
prepareAbout();
prepareSupportProject();
prepareMode();
prepareAngles();
prepareRadix();
@ -144,28 +140,6 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Sha
prepareLanguagePreference(preference);
prepareThemePreference(preference);
getCheckout().whenReady(new Checkout.EmptyListener() {
@Override
public void onReady(@Nonnull BillingRequests requests) {
requests.isPurchased(ProductTypes.IN_APP, "ad_free", new RequestListener<Boolean>() {
@Override
public void onSuccess(@Nonnull Boolean purchased) {
final Preference supportProject = findPreference("prefs.supportProject");
if (supportProject != null) {
supportProject.setEnabled(!purchased);
supportProject.setSelectable(!purchased);
}
onShowAd(!purchased);
}
@Override
public void onError(int i, @Nonnull Exception e) {
onShowAd(false);
}
});
}
});
}
private void prepareReportBug() {
@ -177,20 +151,6 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Sha
return true;
}
});
}
private void prepareSupportProject() {
final Preference supportProject = findPreference("prefs.supportProject");
supportProject.setEnabled(false);
supportProject.setSelectable(false);
supportProject.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(getActivity(), PurchaseDialogActivity.class));
return true;
}
});
}
private void prepareScreens() {
@ -385,11 +345,6 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Sha
});
}
@Nonnull
private Checkout getCheckout() {
return ((PreferencesActivity) getActivity()).getCheckout();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (Preferences.Onscreen.showAppIcon.isSameKey(key)) {
@ -409,58 +364,10 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Sha
prepareNumberFormatExamplesPreference();
}
@Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
@Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
@Override
public void onDestroyView() {
if (adView != null) {
adView.destroy();
}
super.onDestroyView();
}
@Override
public void onDestroy() {
bus.unregister(this);
preferences.unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
protected void onShowAd(boolean show) {
if (getView() == null) {
return;
}
final View root = getView();
if (!(root instanceof ViewGroup)) return;
final ViewGroup container = (ViewGroup) root;
if (show) {
if (adView != null) return;
adView = new AdView(getActivity());
adView.show();
container.addView(adView);
} else {
if (adView == null) return;
container.removeView(adView);
adView.hide();
adView = null;
}
}
}

View File

@ -1,160 +0,0 @@
/*
* Copyright 2013 serso aka se.solovyev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Contact details
*
* Email: se.solovyev@gmail.com
* Site: http://se.solovyev.org
*/
package org.solovyev.android.calculator.preferences;
import static org.solovyev.android.calculator.App.cast;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.BaseDialogFragment;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.checkout.ActivityCheckout;
import org.solovyev.android.checkout.Billing;
import org.solovyev.android.checkout.BillingRequests;
import org.solovyev.android.checkout.Checkout;
import org.solovyev.android.checkout.ProductTypes;
import org.solovyev.android.checkout.Purchase;
import org.solovyev.android.checkout.RequestListener;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
public class PurchaseDialogActivity extends AppCompatActivity implements RequestListener<Purchase> {
@Inject
Billing billing;
@Inject
Ga ga;
ActivityCheckout checkout;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cast(getApplication()).getComponent().inject(this);
if (savedInstanceState == null) {
App.showDialog(new PurchaseDialogFragment(), PurchaseDialogFragment.FRAGMENT_TAG, getSupportFragmentManager());
}
checkout = Checkout.forActivity(this, billing);
checkout.start();
checkout.createPurchaseFlow(this);
}
private void purchase() {
checkout.whenReady(new Checkout.EmptyListener() {
@Override
public void onReady(@Nonnull BillingRequests requests) {
requests.purchase(ProductTypes.IN_APP, "ad_free", null, checkout.getPurchaseFlow());
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
checkout.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onDestroy() {
checkout.destroyPurchaseFlow();
checkout.stop();
super.onDestroy();
}
public void onDialogClosed() {
final Fragment fragment = getSupportFragmentManager().findFragmentByTag(PurchaseDialogFragment.FRAGMENT_TAG);
if (fragment == null) {
// activity is closing
return;
}
finish();
}
@Override
public void onSuccess(@Nonnull Purchase result) {
finish();
}
@Override
public void onError(int response, @Nonnull Exception e) {
finish();
}
public static class PurchaseDialogFragment extends BaseDialogFragment {
public static final String FRAGMENT_TAG = "purchase-dialog";
@Nullable
private PurchaseDialogActivity activity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.activity = (PurchaseDialogActivity) activity;
}
@Override
protected void onPrepareDialog(@NonNull AlertDialog.Builder builder) {
super.onPrepareDialog(builder);
builder.setTitle(R.string.cpp_purchase_title);
builder.setMessage(R.string.cpp_purchase_text);
builder.setPositiveButton(R.string.cpp_continue, null);
}
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
if (activity != null) {
activity.purchase();
}
break;
default:
super.onClick(dialog, which);
break;
}
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (activity != null) {
activity.onDialogClosed();
activity = null;
}
}
}
}

View File

@ -1,39 +0,0 @@
package org.solovyev.android.checkout;
import androidx.annotation.NonNull;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* App-wide {@link Checkout} which counts how many times it has been started.
*/
@Singleton
public class CppCheckout extends Checkout {
private int started = 0;
@Inject
public CppCheckout(@NonNull Billing billing) {
super(null, billing);
}
@Override
public void stop() {
Check.isMainThread();
Check.isTrue(started > 0, "Must be started first");
started--;
if (started == 0) {
super.stop();
}
started = Math.max(0, started);
}
@Override
public void start(Listener listener) {
Check.isMainThread();
started++;
if (started == 1) {
super.start(listener);
}
}
}

View File

@ -29,11 +29,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.solovyev.android.calculator.AdView style="@style/CppAd" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/entities_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</LinearLayout>
</LinearLayout>

View File

@ -29,12 +29,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.solovyev.android.calculator.AdView style="@style/CppAd" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</LinearLayout>
</LinearLayout>

View File

@ -28,11 +28,11 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/history_expression"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -40,18 +40,18 @@
android:hint="@string/c_history_expression"
android:inputType="none"
tools:ignore="Deprecated" />
</android.support.design.widget.TextInputLayout>
</com.google.android.material.textfield.TextInputLayout>
<android.support.design.widget.TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/history_comment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/c_history_comment"
android:inputType="text" />
</android.support.design.widget.TextInputLayout>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View File

@ -24,13 +24,7 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="screen-main">
<Preference
android:defaultValue="false"
android:key="prefs.supportProject"
android:summary="@string/c_calc_ad_free_summary"
android:title="@string/c_calc_ad_free_title" />
<PreferenceCategory
android:key="category-basic"
android:title="@string/cpp_prefs_basic">

BIN
assets/intro.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

View File

@ -13,8 +13,6 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
}
}

1
measure/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

9
measure/build.gradle Normal file
View File

@ -0,0 +1,9 @@
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
sourceCompatibility = "7"
targetCompatibility = "7"

View File

@ -0,0 +1,178 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.measure.converter.AddConverter;
import javax.measure.converter.RationalConverter;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
import javax.measure.unit.Unit;
/**
* <p> This class represents a measure whose value is an arbitrary-precision
* decimal number.</p>
*
* <p> When converting, applications may supply the
* <code>java.math.Context</code>:[code]
* DecimalMeasure<Velocity> c = DecimalMeasure.valueOf("299792458 m/s");
* DecimalMeasure<Velocity> milesPerHour = c.to(MILES_PER_HOUR, MathContext.DECIMAL128);
* System.out.println(milesPerHour);
*
* > 670616629.3843951324266284896206156 mph
* [/code]
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.3, October 3, 2007
*/
public class DecimalMeasure<Q extends Quantity> extends Measure<BigDecimal, Q> {
/**
* Holds the BigDecimal value.
*/
private final BigDecimal _value;
/**
* Holds the unit.
*/
private final Unit<Q> _unit;
/**
* Creates a decimal measure for the specified number stated in the
* specified unit.
*/
public DecimalMeasure(BigDecimal value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
/**
* Returns the decimal measure for the specified number stated in the
* specified unit.
*
* @param decimal the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> DecimalMeasure<Q> valueOf(
BigDecimal decimal, Unit<Q> unit) {
return new DecimalMeasure<Q>(decimal, unit);
}
/**
* Returns the decimal measure for the specified textual representation.
* This method first reads the <code>BigDecimal</code> value, then
* the unit if any (value and unit should be separated by white spaces).
*
* @param csq the decimal measure representation (including unit if any).
* @throws NumberFormatException if the specified character sequence is
* not a valid representation of decimal measure.
*/
@SuppressWarnings("unchecked")
public static <Q extends Quantity> DecimalMeasure<Q> valueOf(CharSequence csq) {
String str = csq.toString();
int numberLength = str.length();
int unitStartIndex = -1;
for (int i=0; i < str.length(); i++) {
if (Character.isWhitespace(str.charAt(i))) {
for (int j=i+1; j < str.length(); j++) {
if (!Character.isWhitespace(str.charAt(j))) {
unitStartIndex = j;
break;
}
}
numberLength = i;
break;
}
}
BigDecimal decimal = new BigDecimal(str.substring(0, numberLength));
Unit unit = Unit.ONE;
if (unitStartIndex > 0) {
unit = Unit.valueOf(str.substring(unitStartIndex));
}
return new DecimalMeasure<Q>(decimal, unit);
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public BigDecimal getValue() {
return _value;
}
/**
* Returns the decimal measure equivalent to this measure but stated in the
* specified unit. This method will raise an ArithmeticException if the
* resulting measure does not have a terminating decimal expansion.
*
* @param unit the new measurement unit.
* @return the measure stated in the specified unit.
* @throws ArithmeticException if the converted measure value does not have
* a terminating decimal expansion
* @see #to(Unit, MathContext)
*/
@Override
public DecimalMeasure<Q> to(Unit<Q> unit) {
return to(unit, null);
}
/**
* Returns the decimal measure equivalent to this measure but stated in the
* specified unit, the conversion is performed using the specified math
* context.
*
* @param unit the new measurement unit.
* @param mathContext the mathContext used to convert
* <code>BigDecimal</code> values or <code>null</code> if none.
* @return the measure stated in the specified unit.
* @throws ArithmeticException if the result is inexact but the
* rounding mode is <code>MathContext.UNNECESSARY</code> or
* <code>mathContext.precision == 0</tt> and the quotient has a
* non-terminating decimal expansion.
*/
public DecimalMeasure<Q> to(Unit<Q> unit, MathContext mathContext) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
if (cvtr instanceof RationalConverter) {
RationalConverter factor = (RationalConverter) cvtr;
BigDecimal dividend = BigDecimal.valueOf(factor.getDividend());
BigDecimal divisor = BigDecimal.valueOf(factor.getDivisor());
BigDecimal result = mathContext == null ?
_value.multiply(dividend).divide(divisor) :
_value.multiply(dividend, mathContext).divide(divisor, mathContext);
return new DecimalMeasure<Q>(result, unit);
} else if (cvtr.isLinear()) {
BigDecimal factor = BigDecimal.valueOf(cvtr.convert(1.0));
BigDecimal result = mathContext == null ?
_value.multiply(factor) : _value.multiply(factor, mathContext);
return new DecimalMeasure<Q>(result, unit);
} else if (cvtr instanceof AddConverter) {
BigDecimal offset = BigDecimal.valueOf(((AddConverter)cvtr).getOffset());
BigDecimal result = mathContext == null ?
_value.add(offset) : _value.add(offset, mathContext);
return new DecimalMeasure<Q>(result, unit);
} else { // Non-linear and not an offset, convert the double value.
BigDecimal result = BigDecimal.valueOf(cvtr.convert(_value.doubleValue()));
return new DecimalMeasure<Q>(result, unit);
}
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value.doubleValue();
return _unit.getConverterTo(unit).convert(_value.doubleValue());
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,76 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import javax.measure.quantity.Quantity;
import javax.measure.unit.Unit;
/**
* <p> This interface represents the measurable, countable, or comparable
* property or aspect of a thing.</p>
*
* <p> Implementing instances are typically the result of a measurement:[code]
* Measurable<Mass> weight = Measure.valueOf(180.0, POUND);
* [/code]
* They can also be created from custom classes:[code]
* class Delay implements Measurable<Duration> {
* private long nanoSeconds; // Implicit internal unit.
* public double doubleValue(Unit<Velocity> unit) { ... }
* public long longValue(Unit<Velocity> unit) { ... }
* }
* Thread.wait(new Delay(24, HOUR)); // Assuming Thread.wait(Measurable<Duration>) method.
* [/code]</p>
*
* <p> Although measurable instances are for the most part scalar quantities;
* more complex implementations (e.g. vectors, data set) are allowed as
* long as an aggregate magnitude can be determined. For example:[code]
* class Velocity3D implements Measurable<Velocity> {
* private double x, y, z; // Meter per seconds.
* public double doubleValue(Unit<Velocity> unit) { ... } // Returns vector norm.
* ...
* }
* class Sensors<Q extends Quantity> extends Measure<double[], Q> {
* public doubleValue(Unit<Q> unit) { ... } // Returns median value.
* ...
* } [/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.1, June 8, 2007
*/
public interface Measurable<Q extends Quantity> extends Comparable<Measurable<Q>> {
/**
* Returns the value of this measurable stated in the specified unit as
* a <code>double</code>. If the measurable has too great a magnitude to
* be represented as a <code>double</code>, it will be converted to
* <code>Double.NEGATIVE_INFINITY</code> or
* <code>Double.POSITIVE_INFINITY</code> as appropriate.
*
* @param unit the unit in which this measurable value is stated.
* @return the numeric value after conversion to type <code>double</code>.
*/
double doubleValue(Unit<Q> unit);
/**
* Returns the estimated integral value of this measurable stated in
* the specified unit as a <code>long</code>.
*
* <p> Note: This method differs from the <code>Number.longValue()</code>
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).</p>
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type <code>long</code>.
* @throws ArithmeticException if this quantity cannot be represented
* as a <code>long</code> number in the specified unit.
*/
long longValue(Unit<Q> unit) throws ArithmeticException;
}

View File

@ -0,0 +1,449 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.measure.quantity.Quantity;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;
/**
* <p> This class represents the result of a measurement stated in a
* known unit.</p>
*
* <p> There is no constraint upon the measurement value itself: scalars,
* vectors, or even data sets are valid values as long as
* an aggregate magnitude can be determined (see {@link Measurable}).</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public abstract class Measure<V, Q extends Quantity> implements Measurable<Q>,
Serializable {
/**
* Default constructor.
*/
protected Measure() {
}
/**
* Returns the scalar measure for the specified <code>double</code>
* stated in the specified unit.
*
* @param doubleValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Double, Q> valueOf(
double doubleValue, Unit<Q> unit) {
return new Double<Q>(doubleValue, unit);
}
/**
* Returns the scalar measure for the specified <code>double</code>
* stated in the specified unit.
*
* @param longValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Long, Q> valueOf(
long longValue, Unit<Q> unit) {
return new Long<Q>(longValue, unit);
}
/**
* Returns the scalar measure for the specified <code>float</code>
* stated in the specified unit.
*
* @param floatValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Float, Q> valueOf(
float floatValue, Unit<Q> unit) {
return new Float<Q>(floatValue, unit);
}
/**
* Returns the scalar measure for the specified <code>int</code>
* stated in the specified unit.
*
* @param intValue the measurement value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> Measure<java.lang.Integer, Q> valueOf(
int intValue, Unit<Q> unit) {
return new Integer<Q>(intValue, unit);
}
/**
* Returns the measurement value of this measure.
*
* @return the measurement value.
*/
public abstract V getValue();
/**
* Returns the measurement unit of this measure.
*
* @return the measurement unit.
*/
public abstract Unit<Q> getUnit();
/**
* Returns the measure equivalent to this measure but stated in the
* specified unit. This method may result in lost of precision
* (e.g. measure of integral value).
*
* @param unit the new measurement unit.
* @return the measure stated in the specified unit.
*/
public abstract Measure<V, Q> to(Unit<Q> unit);
/**
* Returns the value of this measure stated in the specified unit as
* a <code>double</code>. If the measure has too great a magnitude to
* be represented as a <code>double</code>, it will be converted to
* <code>Double.NEGATIVE_INFINITY</code> or
* <code>Double.POSITIVE_INFINITY</code> as appropriate.
*
* @param unit the unit in which this measure is stated.
* @return the numeric value after conversion to type <code>double</code>.
*/
public abstract double doubleValue(Unit<Q> unit);
/**
* Returns the estimated integral value of this measure stated in
* the specified unit as a <code>long</code>.
*
* <p> Note: This method differs from the <code>Number.longValue()</code>
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).</p>
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type <code>long</code>.
* @throws ArithmeticException if this quantity cannot be represented
* as a <code>long</code> number in the specified unit.
*/
public long longValue(Unit<Q> unit) throws ArithmeticException {
double doubleValue = doubleValue(unit);
if (java.lang.Double.isNaN(doubleValue)
|| (doubleValue < java.lang.Long.MIN_VALUE)
|| (doubleValue > java.lang.Long.MAX_VALUE))
throw new ArithmeticException(doubleValue + " " + unit
+ " cannot be represented as long");
return Math.round(doubleValue);
}
/**
* Returns the value of this measure stated in the specified unit as a
* <code>float</code>. If the measure has too great a magnitude to be
* represented as a <code>float</code>, it will be converted to
* <code>Float.NEGATIVE_INFINITY</code> or
* <code>Float.POSITIVE_INFINITY</code> as appropriate.
*
* @param unit the unit in which the measure is stated.
* @return the numeric value after conversion to type <code>float</code>.
*/
public float floatValue(Unit<Q> unit) {
return (float) doubleValue(unit);
}
/**
* Returns the estimated integral value of this measure stated in
* the specified unit as a <code>int</code>.
*
* <p> Note: This method differs from the <code>Number.intValue()</code>
* in the sense that the closest integer value is returned
* and an ArithmeticException is raised instead
* of a bit truncation in case of overflow (safety critical).</p>
*
* @param unit the unit in which the measurable value is stated.
* @return the numeric value after conversion to type <code>int</code>.
* @throws ArithmeticException if this quantity cannot be represented
* as a <code>int</code> number in the specified unit.
*/
public int intValue(Unit<Q> unit) {
long longValue = longValue(unit);
if ((longValue > java.lang.Integer.MAX_VALUE)
|| (longValue < java.lang.Integer.MIN_VALUE))
throw new ArithmeticException("Overflow");
return (int) longValue;
}
/**
* Compares this measure against the specified object for
* strict equality (same unit and amount).
* To compare measures stated using different units the
* {@link #compareTo} method should be used.
*
* @param obj the object to compare with.
* @return <code>true</code> if both objects are identical (same
* unit and same amount); <code>false</code> otherwise.
*/
@SuppressWarnings("unchecked")
public boolean equals(Object obj) {
if (!(obj instanceof Measure))
return false;
Measure that = (Measure) obj;
return this.getUnit().equals(that.getUnit())
&& this.getValue().equals(that.getValue());
}
/**
* Returns the hash code for this scalar.
*
* @return the hash code value.
*/
public int hashCode() {
return getUnit().hashCode() + getValue().hashCode();
}
/**
* Returns the <code>String</code> representation of this measure
* The string produced for a given measure is always the same;
* it is not affected by locale. This means that it can be used
* as a canonical string representation for exchanging data,
* or as a key for a Hashtable, etc. Locale-sensitive
* measure formatting and parsing is handled by the {@link
* MeasureFormat} class and its subclasses.
*
* @return the string representation of this measure.
*/
public String toString() {
if (getUnit() instanceof CompoundUnit)
return MeasureFormat.DEFAULT.formatCompound(doubleValue(getUnit()),
getUnit(), new StringBuffer(), null).toString();
return getValue() + " " + getUnit();
}
/**
* Compares this measure to the specified measurable quantity.
* This method compares the {@link Measurable#doubleValue(Unit)} of
* both this measure and the specified measurable stated in the
* same unit (this measure's {@link #getUnit() unit}).
*
* @return a negative integer, zero, or a positive integer as this measure
* is less than, equal to, or greater than the specified measurable
* quantity.
* @return <code>Double.compare(this.doubleValue(getUnit()),
* that.doubleValue(getUnit()))</code>
*/
public int compareTo(Measurable<Q> that) {
return java.lang.Double.compare(doubleValue(getUnit()), that
.doubleValue(getUnit()));
}
/**
* Holds scalar implementation for <code>double</code> values.
*/
private static final class Double<Q extends Quantity> extends
Measure<java.lang.Double, Q> {
private final double _value;
private final Unit<Q> _unit;
public Double(double value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Double getValue() {
return _value;
}
@Override
public Measure<java.lang.Double, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Double<Q>(doubleValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for <code>long</code> values.
*/
private static final class Long<Q extends Quantity> extends
Measure<java.lang.Long, Q> {
private final long _value;
private final Unit<Q> _unit;
public Long(long value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Long getValue() {
return _value;
}
@Override
public Measure<java.lang.Long, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Long<Q>(longValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
public long longValue(Unit<Q> unit) throws ArithmeticException {
if ((unit == _unit) || (unit.equals(_unit)))
return _value; // No conversion, returns value directly.
return super.longValue(unit);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for <code>float</code> values.
*/
private static final class Float<Q extends Quantity> extends
Measure<java.lang.Float, Q> {
private final float _value;
private final Unit<Q> _unit;
public Float(float value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Float getValue() {
return _value;
}
@Override
public Measure<java.lang.Float, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Float<Q>(floatValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
private static final long serialVersionUID = 1L;
}
/**
* Holds scalar implementation for <code>long</code> values.
*/
private static final class Integer<Q extends Quantity> extends
Measure<java.lang.Integer, Q> {
private final int _value;
private final Unit<Q> _unit;
public Integer(int value, Unit<Q> unit) {
_value = value;
_unit = unit;
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public java.lang.Integer getValue() {
return _value;
}
@Override
public Measure<java.lang.Integer, Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
return new Integer<Q>(intValue(unit), unit);
}
public double doubleValue(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return _value;
return _unit.getConverterTo(unit).convert(_value);
}
public long longValue(Unit<Q> unit) throws ArithmeticException {
if ((unit == _unit) || (unit.equals(_unit)))
return _value; // No conversion, returns value directly.
return super.longValue(unit);
}
private static final long serialVersionUID = 1L;
}
/**
* @deprecated {@link DecimalMeasure} should be used directly.
*/
public static <Q extends Quantity> Measure<BigDecimal, Q> valueOf(
BigDecimal decimal, Unit<Q> unit) {
return DecimalMeasure.valueOf(decimal, unit);
}
/**
* @deprecated {@link DecimalMeasure} should be used directly and
* <code>MathContext</code> specified explicitly when
* {@link DecimalMeasure#to(Unit, MathContext) converting}.
*/
public static <Q extends Quantity> Measure<BigDecimal, Q> valueOf(
BigDecimal decimal, Unit<Q> unit, MathContext mathContext) {
return DecimalMeasure.valueOf(decimal, unit);
}
/**
* @deprecated {@link VectorMeasure} should be used directly.
*/
public static <Q extends Quantity> Measure<double[], Q> valueOf(
double[] components, Unit<Q> unit) {
return VectorMeasure.valueOf(components, unit);
}
}

View File

@ -0,0 +1,169 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import java.math.BigDecimal;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
/**
* <p> This class provides the interface for formatting and parsing {@link
* Measure measures}.</p>
*
* <p> As a minimum, instances of this class should be able to parse/format
* measure using {@link CompoundUnit}. </p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public abstract class MeasureFormat extends Format {
/**
* Returns the measure format for the default locale.
*
* @return <code>getInstance(Number.getInstance(), Unit.getInstance())</code>
*/
public static MeasureFormat getInstance() {
return DEFAULT;
}
static final NumberUnit DEFAULT = new NumberUnit(NumberFormat
.getInstance(), UnitFormat.getInstance());
/**
* Returns the measure format using the specified number format and
* unit format (the number and unit are separated by a space).
*
* @param numberFormat the number format.
* @param unitFormat the unit format.
* @return the corresponding format.
*/
public static MeasureFormat getInstance(NumberFormat numberFormat,
UnitFormat unitFormat) {
return new NumberUnit(numberFormat, unitFormat);
}
// Holds default implementation.
static final class NumberUnit extends MeasureFormat {
private final NumberFormat _numberFormat;
private final UnitFormat _unitFormat;
private NumberUnit(NumberFormat numberFormat, UnitFormat unitFormat) {
_numberFormat = numberFormat;
_unitFormat = unitFormat;
}
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos) {
Measure<?, ?> measure = (Measure<?, ?>) obj;
Object value = measure.getValue();
Unit<?> unit = measure.getUnit();
if (value instanceof Number) {
if (unit instanceof CompoundUnit)
return formatCompound(((Number) value).doubleValue(),
(CompoundUnit<?>) unit, toAppendTo, pos);
_numberFormat.format(value, toAppendTo, pos);
} else {
toAppendTo.append(value);
}
if (!measure.getUnit().equals(Unit.ONE)) {
toAppendTo.append(' ');
_unitFormat.format(unit, toAppendTo, pos);
}
return toAppendTo;
}
// Measure using Compound unit have no separators in their representation.
StringBuffer formatCompound(double value, Unit<?> unit,
StringBuffer toAppendTo, FieldPosition pos) {
if (!(unit instanceof CompoundUnit)) {
toAppendTo.append((long) value);
return _unitFormat.format(unit, toAppendTo, pos);
}
Unit<?> high = ((CompoundUnit<?>) unit).getHigher();
Unit<?> low = ((CompoundUnit<?>) unit).getLower(); // The unit in which the value is stated.
long highValue = (long) low.getConverterTo(high).convert(value);
double lowValue = value
- high.getConverterTo(low).convert(highValue);
formatCompound(highValue, high, toAppendTo, pos);
formatCompound(lowValue, low, toAppendTo, pos);
return toAppendTo;
}
@Override
public Object parseObject(String source, ParsePosition pos) {
int start = pos.getIndex();
try {
int i = start;
Number value = _numberFormat.parse(source, pos);
if (i == pos.getIndex())
return null; // Cannot parse.
i = pos.getIndex();
if (i >= source.length())
return measureOf(value, Unit.ONE); // No unit.
boolean isCompound = !Character.isWhitespace(source.charAt(i));
if (isCompound)
return parseCompound(value, source, pos);
if (++i >= source.length())
return measureOf(value, Unit.ONE); // No unit.
pos.setIndex(i); // Skips separator.
Unit<?> unit = _unitFormat.parseProductUnit(source, pos);
return measureOf(value, unit);
} catch (ParseException e) {
pos.setIndex(start);
pos.setErrorIndex(e.getErrorOffset());
return null;
}
}
@SuppressWarnings("unchecked")
private Object parseCompound(Number highValue, String source,
ParsePosition pos) throws ParseException {
Unit high = _unitFormat.parseSingleUnit(source, pos);
int i = pos.getIndex();
if (i >= source.length()
|| Character.isWhitespace(source.charAt(i)))
return measureOf(highValue, high);
Measure lowMeasure = (Measure) parseObject(source, pos);
Unit unit = lowMeasure.getUnit();
long l = lowMeasure.longValue(unit)
+ (long) high.getConverterTo(unit).convert(
highValue.longValue());
return Measure.valueOf(l, unit);
}
@SuppressWarnings("unchecked")
private static Measure measureOf(Number value, Unit unit) {
if (value instanceof Double) {
return Measure.valueOf(value.doubleValue(), unit);
} else if (value instanceof Long) {
return Measure.valueOf(value.longValue(), unit);
} else if (value instanceof Float) {
return Measure.valueOf(value.floatValue(), unit);
} else if (value instanceof Integer) {
return Measure.valueOf(value.intValue(), unit);
} else if (value instanceof BigDecimal) {
return DecimalMeasure.valueOf((BigDecimal) value, unit);
} else {
return Measure.valueOf(value.doubleValue(), unit);
}
}
private static final long serialVersionUID = 1L;
}
}

View File

@ -0,0 +1,273 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2007 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;
/**
* <p> This class represents a measurement vector of two or more dimensions.
* For example:[code]
* VectorMeasure<Length> dimension = VectorMeasure.valueOf(12.0, 30.0, 40.0, MILLIMETER);
* VectorMeasure<Velocity> v2d = VectorMeasure.valueOf(-2.2, -3.0, KNOTS);
* VectorMeasure<ElectricCurrent> c2d = VectorMeasure.valueOf(-7.3, 3.5, NANOAMPERE);
* [/code]
* </p>
*
* <p> Subclasses may provide fixed dimensions specializations:[code]
* class Velocity2D extends VectorMeasure<Velocity> {
* public Velocity2D(double x, double y, Unit<Velocity> unit) {
* ...
* }
* }
* [/code]</p>
*
* <p> Measurement vectors may use {@link CompoundUnit compound units}:[code]
* VectorMeasure<Angle> latLong = VectorMeasure.valueOf(12.345, 22.23, DEGREE_ANGLE);
* Unit<Angle> HOUR_MINUTE_SECOND_ANGLE = DEGREE_ANGLE.compound(MINUTE_ANGLE).compound(SECOND_ANGLE);
* System.out.println(latLong.to(HOUR_MINUTE_SECOND_ANGLE));
*
* > [12°19'42", 22°12'48"] [/code]</p>
*
* <p> Instances of this class (and sub-classes) are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.3, October 3, 2007
*/
public abstract class VectorMeasure<Q extends Quantity> extends Measure<double[], Q> {
/**
* Default constructor (for sub-classes).
*/
protected VectorMeasure() {
}
/**
* Returns a 2-dimensional measurement vector.
*
* @param x the first vector component value.
* @param y the second vector component value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> VectorMeasure<Q> valueOf(
double x, double y, Unit<Q> unit) {
return new TwoDimensional<Q>(x, y, unit);
}
/**
* Returns a 3-dimensional measurement vector.
*
* @param x the first vector component value.
* @param y the second vector component value.
* @param z the third vector component value.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> VectorMeasure<Q> valueOf(
double x, double y, double z, Unit<Q> unit) {
return new ThreeDimensional<Q>(x, y, z, unit);
}
/**
* Returns a multi-dimensional measurement vector.
*
* @param components the vector component values.
* @param unit the measurement unit.
*/
public static <Q extends Quantity> VectorMeasure<Q> valueOf(double[] components,
Unit<Q> unit) {
return new MultiDimensional<Q>(components, unit);
}
/**
* Returns the measurement vector equivalent to this one but stated in the
* specified unit.
*
* @param unit the new measurement unit.
* @return the vector measure stated in the specified unit.
*/
public abstract VectorMeasure<Q> to(Unit<Q> unit);
/**
* Returns the norm of this measurement vector stated in the specified
* unit.
*
* @param unit the unit in which the norm is stated.
* @return <code>|this|</code>
*/
public abstract double doubleValue(Unit<Q> unit);
/**
* Returns the <code>String</code> representation of this measurement
* vector (for example <code>[2.3 m/s, 5.6 m/s]</code>).
*
* @return the textual representation of the measurement vector.
*/
public String toString() {
double[] values = getValue();
Unit<Q> unit = getUnit();
StringBuffer tmp = new StringBuffer();
tmp.append('[');
for (double v : values) {
if (tmp.length() > 1) {
tmp.append(", ");
}
if (unit instanceof CompoundUnit) {
MeasureFormat.DEFAULT.formatCompound(v, unit, tmp, null);
} else {
tmp.append(v).append(" ").append(unit);
}
}
tmp.append("] ");
return tmp.toString();
}
// Holds 2-dimensional implementation.
private static class TwoDimensional<Q extends Quantity> extends VectorMeasure<Q> {
private final double _x;
private final double _y;
private final Unit<Q> _unit;
private TwoDimensional(double x, double y, Unit<Q> unit) {
_x = x;
_y = y;
_unit = unit;
}
@Override
public double doubleValue(Unit<Q> unit) {
double norm = Math.sqrt(_x * _x + _y * _y);
if ((unit == _unit) || (unit.equals(_unit)))
return norm;
return _unit.getConverterTo(unit).convert(norm);
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public double[] getValue() {
return new double[] { _x, _y };
}
@Override
public TwoDimensional<Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
return new TwoDimensional<Q>(cvtr.convert(_x), cvtr.convert(_y), unit);
}
private static final long serialVersionUID = 1L;
}
// Holds 3-dimensional implementation.
private static class ThreeDimensional<Q extends Quantity> extends VectorMeasure<Q> {
private final double _x;
private final double _y;
private final double _z;
private final Unit<Q> _unit;
private ThreeDimensional(double x, double y, double z, Unit<Q> unit) {
_x = x;
_y = y;
_z = z;
_unit = unit;
}
@Override
public double doubleValue(Unit<Q> unit) {
double norm = Math.sqrt(_x * _x + _y * _y + _z * _z);
if ((unit == _unit) || (unit.equals(_unit)))
return norm;
return _unit.getConverterTo(unit).convert(norm);
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public double[] getValue() {
return new double[] { _x, _y, _z };
}
@Override
public ThreeDimensional<Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
return new ThreeDimensional<Q>(cvtr.convert(_x), cvtr.convert(_y), cvtr.convert(_z), unit);
}
private static final long serialVersionUID = 1L;
}
// Holds multi-dimensional implementation.
private static class MultiDimensional<Q extends Quantity> extends VectorMeasure<Q> {
private final double[] _components;
private final Unit<Q> _unit;
private MultiDimensional(double[] components, Unit<Q> unit) {
_components = components.clone();
_unit = unit;
}
@Override
public double doubleValue(Unit<Q> unit) {
double normSquare = _components[0] * _components[0];
for (int i=1, n=_components.length; i < n;) {
double d = _components[i++];
normSquare += d * d;
}
if ((unit == _unit) || (unit.equals(_unit)))
return Math.sqrt(normSquare);
return _unit.getConverterTo(unit).convert(Math.sqrt(normSquare));
}
@Override
public Unit<Q> getUnit() {
return _unit;
}
@Override
public double[] getValue() {
return _components.clone();
}
@Override
public MultiDimensional<Q> to(Unit<Q> unit) {
if ((unit == _unit) || (unit.equals(_unit)))
return this;
UnitConverter cvtr = _unit.getConverterTo(unit);
double[] newValues = new double[_components.length];
for (int i=0; i < _components.length; i++) {
newValues[i] = cvtr.convert(_components[i]);
}
return new MultiDimensional<Q>(newValues, unit);
}
private static final long serialVersionUID = 1L;
}
}

View File

@ -0,0 +1,80 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a converter adding a constant offset
* (approximated as a <code>double</code>) to numeric values.</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class AddConverter extends UnitConverter {
/**
* Holds the offset.
*/
private final double _offset;
/**
* Creates an add converter with the specified offset.
*
* @param offset the offset value.
* @throws IllegalArgumentException if offset is zero (or close to zero).
*/
public AddConverter(double offset) {
if ((float)offset == 0.0)
throw new IllegalArgumentException("Identity converter not allowed");
_offset = offset;
}
/**
* Returns the offset value for this add converter.
*
* @return the offset value.
*/
public double getOffset() {
return _offset;
}
@Override
public UnitConverter inverse() {
return new AddConverter(- _offset);
}
@Override
public double convert(double amount) {
return amount + _offset;
}
@Override
public boolean isLinear() {
return false;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
if (converter instanceof AddConverter) {
double offset = _offset + ((AddConverter)converter)._offset;
return valueOf(offset);
} else {
return super.concatenate(converter);
}
}
private static UnitConverter valueOf(double offset) {
float asFloat = (float) offset;
return asFloat == 0.0f ? UnitConverter.IDENTITY : new AddConverter(offset);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,38 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* Signals that a problem of some sort has occurred either when creating a
* converter between two units or during the conversion itself.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 2, 2006
*/
public class ConversionException extends RuntimeException {
/**
* Constructs a <code>ConversionException</code> with no detail message.
*/
public ConversionException() {
super();
}
/**
* Constructs a <code>ConversionException</code> with the specified detail
* message.
*
* @param message the detail message.
*/
public ConversionException(String message) {
super(message);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,107 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a logarithmic converter. Such converter
* is typically used to create logarithmic unit. For example:[code]
* Unit<Dimensionless> BEL = Unit.ONE.transform(new LogConverter(10).inverse());
* [/code]</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class LogConverter extends UnitConverter {
/**
* Holds the logarithmic base.
*/
private final double _base;
/**
* Holds the natural logarithm of the base.
*/
private final double _logBase;
/**
* Holds the inverse of the natural logarithm of the base.
*/
private final double _invLogBase;
/**
* Holds the inverse of this converter.
*/
private final Inverse _inverse = new Inverse();
/**
* Creates a logarithmic converter having the specified base.
*
* @param base the logarithmic base (e.g. <code>Math.E</code> for
* the Natural Logarithm).
*/
public LogConverter(double base) {
_base = base;
_logBase = Math.log(base);
_invLogBase = 1.0 / _logBase;
}
/**
* Returns the logarithmic base of this converter.
*
* @return the logarithmic base (e.g. <code>Math.E</code> for
* the Natural Logarithm).
*/
public double getBase() {
return _base;
}
@Override
public UnitConverter inverse() {
return _inverse;
}
@Override
public double convert(double amount) {
return _invLogBase * Math.log(amount);
}
@Override
public boolean isLinear() {
return false;
}
/**
* This inner class represents the inverse of the logarithmic converter
* (exponentiation converter).
*/
private class Inverse extends UnitConverter {
@Override
public UnitConverter inverse() {
return LogConverter.this;
}
@Override
public double convert(double amount) {
return Math.exp(_logBase * amount);
}
@Override
public boolean isLinear() {
return false;
}
private static final long serialVersionUID = 1L;
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,86 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a converter multiplying numeric values by a
* constant scaling factor (approximated as a <code>double</code>).
* For exact scaling conversions {@link RationalConverter} is preferred.</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class MultiplyConverter extends UnitConverter {
/**
* Holds the scale factor.
*/
private final double _factor;
/**
* Creates a multiply converter with the specified scale factor.
*
* @param factor the scale factor.
* @throws IllegalArgumentException if offset is one (or close to one).
*/
public MultiplyConverter(double factor) {
if ((float)factor == 1.0)
throw new IllegalArgumentException("Identity converter not allowed");
_factor = factor;
}
/**
* Returns the scale factor.
*
* @return the scale factor.
*/
public double getFactor() {
return _factor;
}
@Override
public UnitConverter inverse() {
return new MultiplyConverter(1.0 / _factor);
}
@Override
public double convert(double amount) {
return _factor * amount;
}
@Override
public boolean isLinear() {
return true;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
if (converter instanceof MultiplyConverter) {
double factor = _factor * ((MultiplyConverter) converter)._factor;
return valueOf(factor);
} else if (converter instanceof RationalConverter) {
double factor = _factor
* ((RationalConverter) converter).getDividend()
/ ((RationalConverter) converter).getDivisor();
return valueOf(factor);
} else {
return super.concatenate(converter);
}
}
private static UnitConverter valueOf(double factor) {
float asFloat = (float) factor;
return asFloat == 1.0f ? UnitConverter.IDENTITY
: new MultiplyConverter(factor);
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,127 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
/**
* <p> This class represents a converter multiplying numeric values by an
* exact scaling factor (represented as the quotient of two
* <code>long</code> numbers).</p>
*
* <p> Instances of this class are immutable.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class RationalConverter extends UnitConverter {
/**
* Holds the converter dividend.
*/
private final long _dividend;
/**
* Holds the converter divisor (always positive).
*/
private final long _divisor;
/**
* Creates a rational converter with the specified dividend and
* divisor.
*
* @param dividend the dividend.
* @param divisor the positive divisor.
* @throws IllegalArgumentException if <code>divisor &lt; 0</code>
* @throws IllegalArgumentException if <code>dividend == divisor</code>
*/
public RationalConverter(long dividend, long divisor) {
if (divisor < 0)
throw new IllegalArgumentException("Negative divisor");
if (dividend == divisor)
throw new IllegalArgumentException("Identity converter not allowed");
_dividend = dividend;
_divisor = divisor;
}
/**
* Returns the dividend for this rational converter.
*
* @return this converter dividend.
*/
public long getDividend() {
return _dividend;
}
/**
* Returns the positive divisor for this rational converter.
*
* @return this converter divisor.
*/
public long getDivisor() {
return _divisor;
}
@Override
public UnitConverter inverse() {
return _dividend < 0 ? new RationalConverter(-_divisor, -_dividend)
: new RationalConverter(_divisor, _dividend);
}
@Override
public double convert(double amount) {
return amount * _dividend / _divisor;
}
@Override
public boolean isLinear() {
return true;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
if (converter instanceof RationalConverter) {
RationalConverter that = (RationalConverter) converter;
long dividendLong = this._dividend * that._dividend;
long divisorLong = this._divisor * that._divisor;
double dividendDouble = ((double)this._dividend) * that._dividend;
double divisorDouble = ((double)this._divisor) * that._divisor;
if ((dividendLong != dividendDouble) ||
(divisorLong != divisorDouble)) { // Long overflows.
return new MultiplyConverter(dividendDouble / divisorDouble);
}
long gcd = gcd(dividendLong, divisorLong);
return RationalConverter.valueOf(dividendLong / gcd, divisorLong / gcd);
} else if (converter instanceof MultiplyConverter) {
return converter.concatenate(this);
} else {
return super.concatenate(converter);
}
}
private static UnitConverter valueOf(long dividend, long divisor) {
return (dividend == 1L) && (divisor == 1L) ? UnitConverter.IDENTITY
: new RationalConverter(dividend, divisor);
}
/**
* Returns the greatest common divisor (Euclid's algorithm).
*
* @param m the first number.
* @param nn the second number.
* @return the greatest common divisor.
*/
private static long gcd(long m, long n) {
if (n == 0L) {
return m;
} else {
return gcd(n, m % n);
}
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,188 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.converter;
import java.io.Serializable;
/**
* <p> This class represents a converter of numeric values.</p>
*
* <p> It is not required for sub-classes to be immutable
* (e.g. currency converter).</p>
*
* <p> Sub-classes must ensure unicity of the {@link #IDENTITY identity}
* converter. In other words, if the result of an operation is equivalent
* to the identity converter, then the unique {@link #IDENTITY} instance
* should be returned.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public abstract class UnitConverter implements Serializable {
/**
* Holds the identity converter (unique). This converter does nothing
* (<code>ONE.convert(x) == x</code>).
*/
public static final UnitConverter IDENTITY = new Identity();
/**
* Default constructor.
*/
protected UnitConverter() {
}
/**
* Returns the inverse of this converter. If <code>x</code> is a valid
* value, then <code>x == inverse().convert(convert(x))</code> to within
* the accuracy of computer arithmetic.
*
* @return the inverse of this converter.
*/
public abstract UnitConverter inverse();
/**
* Converts a double value.
*
* @param x the numeric value to convert.
* @return the converted numeric value.
* @throws ConversionException if an error occurs during conversion.
*/
public abstract double convert(double x) throws ConversionException;
/**
* Indicates if this converter is linear. A converter is linear if
* <code>convert(u + v) == convert(u) + convert(v)</code> and
* <code>convert(r * u) == r * convert(u)</code>.
* For linear converters the following property always hold:[code]
* y1 = c1.convert(x1);
* y2 = c2.convert(x2);
* then y1*y2 = c1.concatenate(c2).convert(x1*x2)[/code]
*
* @return <code>true</code> if this converter is linear;
* <code>false</code> otherwise.
*/
public abstract boolean isLinear();
/**
* Indicates whether this converter is considered the same as the
* converter specified. To be considered equal this converter
* concatenated with the one specified must returns the {@link #IDENTITY}.
*
* @param cvtr the converter with which to compare.
* @return <code>true</code> if the specified object is a converter
* considered equals to this converter;<code>false</code> otherwise.
*/
public boolean equals(Object cvtr) {
if (!(cvtr instanceof UnitConverter)) return false;
return this.concatenate(((UnitConverter)cvtr).inverse()) == IDENTITY;
}
/**
* Returns a hash code value for this converter. Equals object have equal
* hash codes.
*
* @return this converter hash code value.
* @see #equals
*/
public int hashCode() {
return Float.floatToIntBits((float)convert(1.0));
}
/**
* Concatenates this converter with another converter. The resulting
* converter is equivalent to first converting by the specified converter,
* and then converting by this converter.
*
* <p>Note: Implementations must ensure that the {@link #IDENTITY} instance
* is returned if the resulting converter is an identity
* converter.</p>
*
* @param converter the other converter.
* @return the concatenation of this converter with the other converter.
*/
public UnitConverter concatenate(UnitConverter converter) {
return (converter == IDENTITY) ? this : new Compound(converter, this);
}
/**
* This inner class represents the identity converter (singleton).
*/
private static final class Identity extends UnitConverter {
@Override
public UnitConverter inverse() {
return this;
}
@Override
public double convert(double x) {
return x;
}
@Override
public boolean isLinear() {
return true;
}
@Override
public UnitConverter concatenate(UnitConverter converter) {
return converter;
}
private static final long serialVersionUID = 1L;
}
/**
* This inner class represents a compound converter.
*/
private static final class Compound extends UnitConverter {
/**
* Holds the first converter.
*/
private final UnitConverter _first;
/**
* Holds the second converter.
*/
private final UnitConverter _second;
/**
* Creates a compound converter resulting from the combined
* transformation of the specified converters.
*
* @param first the first converter.
* @param second the second converter.
*/
private Compound(UnitConverter first, UnitConverter second) {
_first = first;
_second = second;
}
@Override
public UnitConverter inverse() {
return new Compound(_second.inverse(), _first.inverse());
}
@Override
public double convert(double x) {
return _second.convert(_first.convert(x));
}
@Override
public boolean isLinear() {
return _first.isLinear() && _second.isLinear();
}
private static final long serialVersionUID = 1L;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@ -0,0 +1,5 @@
<body>
<p> Provides support for unit conversion.</p>
<h3>UML Diagram</h3>
<IMG alt="UML Diagram" src="doc-files/converter.png">
</body>

View File

@ -0,0 +1,77 @@
<body>
<p> Provides strongly typed measurements to enforce compile-time
check of parameters consistency and avoid interface errors.</p>
<p> Let's take the following example:[code]
class Person {
void setWeight(double weight);
}[/code]
Should the weight be in pound, kilogram ??<br>
Using measures there is no room for error:[code]
class Person {
void setWeight(Measurable<Mass> weight);
}[/code]
Not only the interface is cleaner (the weight has to be of mass type);
but also there is no confusion on the measurement unit:[code]
double weightInKg = weight.doubleValue(KILOGRAM);
double weightInLb = weight.doubleValue(POUND);[/code]
Measurable work hand-in-hand with units (also parameterized).
For example, the following would result in compile-time error:[code]
double weightInLiter = weight.doubleValue(LITER); // Compile error, Unit<Mass> required.
[/code]</p>
<p> Users may create their own {@link javax.measure.Measurable
Measurable} implementation:[code]
public class Period implements Measurable<Duration> {
long nanoseconds;
...
}
public class Distance implements Measurable<Length> {
double meters;
...
}
public class Velocity3D implements Measurable<Velocity> {
double x, y, z; // In meters.
...
}
[/code]</p>
<p> Users may also combine a definite amount (scalar, vector, collection, etc.)
to a unit and make it a {@link javax.measure.Measure Measure} (and
a {@link javax.measure.Measurable Measurable} instance). For example:
[code]
// Scalar measurement (numerical).
person.setWeight(Measure.valueOf(180.0, POUND)); // Measure<Double, Mass>
timer.setPeriod(Measure.valueOf(20, MILLI(SECOND)); // Measure<Integer, Duration>
circuit.setCurrent(Measure.valueOf(Complex.valueOf(2, -3), AMPERE); // (2 - 3i) A
bottle.setPression(Measure.valueOf(Rational.valueOf(20, 100), ATMOSPHERE)); // (20/100) Atm
// Vector measurement.
abstract class MeasureVector<E, Q extends Quantity> extends Measure<E[], Q> {
... // doubleValue(Unit) returns vector norm.
}
MeasureVector<Double, Velocity> v = MeasureVector.valueOf(METRE_PER_SECOND, 1.0, 2.0, 3.0);
plane.setVelocity(v);
// Statistical measurement.
class Average<Q extends Quantity> extends Measure<double[], Q>{
... // doubleValue(Unit) returns average value.
}
sea.setTemperature(Average.valueOf(new double[] { 33.4, 44.55, 32.33} , CELCIUS));
// Measurement with uncertainty (and additional operations).
public class Amount<Q extends Quantity> extends Measurable<Q> {
public Amount(double value, double error, Unit<Q> unit) { ... }
public Amount<Q> plus(Amount<Q> that) {...}
public Amount<?> times(Amount<?> that) {...}
... // doubleValue(Unit) returns estimated value.
}
[/code]</p>
</body>

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate of change of velocity with respect to
* time. The system unit for this quantity is "m/s²" (meter per square second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Acceleration extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Acceleration> UNIT = SI.METRES_PER_SQUARE_SECOND;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the number of elementary entities (molecules, for
* example) of a substance. The system unit for this quantity is "mol" (mole).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface AmountOfSubstance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<AmountOfSubstance> UNIT = SI.MOLE;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the figure formed by two lines diverging from a
* common point. The system unit for this quantity is "rad" (radian).
* This quantity is dimensionless.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Angle extends Dimensionless {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Angle> UNIT = SI.RADIAN;
}

View File

@ -0,0 +1,30 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate of change of angular velocity with respect
* to time. The system unit for this quantity is "rad/s²" (radian per
* square second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface AngularAcceleration extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<AngularAcceleration> UNIT
= new ProductUnit<AngularAcceleration>(SI.RADIAN.divide(SI.SECOND.pow(2)));
}

View File

@ -0,0 +1,30 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate of change of angular displacement
* with respect to time. The system unit for this quantity is "rad/s"
* (radian per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface AngularVelocity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<AngularVelocity> UNIT
= new ProductUnit<AngularVelocity>(SI.RADIAN.divide(SI.SECOND));
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the extent of a planar region or of the surface of
* a solid measured in square units. The system unit for this quantity
* is "" (square meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Area extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Area> UNIT = SI.SQUARE_METRE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a catalytic activity. The system unit for this
* quantity is "kat" (katal).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface CatalyticActivity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<CatalyticActivity> UNIT = SI.KATAL;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a measure of data amount.
* The system unit for this quantity is "bit". This quantity is dimensionless.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface DataAmount extends Dimensionless {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<DataAmount> UNIT = SI.BIT;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the speed of data-transmission.
* The system unit for this quantity is "bit/s" (bit per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface DataRate extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<DataRate> UNIT = new ProductUnit<DataRate>(SI.BIT.divide(SI.SECOND));
}

View File

@ -0,0 +1,25 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.Unit;
/**
* This interface represents a dimensionless quantity.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Dimensionless extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Dimensionless> UNIT = Unit.ONE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a period of existence or persistence. The system
* unit for this quantity is "s" (second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Duration extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Duration> UNIT = SI.SECOND;
}

View File

@ -0,0 +1,32 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the dynamic viscosity.
* The system unit for this quantity is "Pa·s" (Pascal-Second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Viscosity">
* Wikipedia: Viscosity</a>
*/
public interface DynamicViscosity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<DynamicViscosity> UNIT
= new ProductUnit<DynamicViscosity>(SI.PASCAL.times(SI.SECOND));
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric capacitance. The system unit for this
* quantity is "F" (Farad).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricCapacitance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricCapacitance> UNIT = SI.FARAD;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric charge. The system unit for this
* quantity is "C" (Coulomb).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricCharge extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricCharge> UNIT = SI.COULOMB;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric conductance. The system unit for this
* quantity "S" (Siemens).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricConductance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricConductance> UNIT = SI.SIEMENS;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the amount of electric charge flowing past
* a specified circuit point per unit time. The system unit for
* this quantity is "A" (Ampere).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricCurrent extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricCurrent> UNIT = SI.AMPERE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric inductance. The system unit for this
* quantity is "H" (Henry).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricInductance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricInductance> UNIT = SI.HENRY;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric potential or electromotive force.
* The system unit for this quantity is "V" (Volt).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricPotential extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricPotential> UNIT = SI.VOLT;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an electric resistance.
* The system unit for this quantity is "Ω" (Ohm).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface ElectricResistance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<ElectricResistance> UNIT = SI.OHM;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the capacity of a physical system to do work.
* The system unit for this quantity "J" (Joule).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Energy extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Energy> UNIT = SI.JOULE;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a quantity that tends to produce an acceleration
* of a body in the direction of its application. The system unit for
* this quantity is "N" (Newton).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Force extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Force> UNIT = SI.NEWTON;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the number of times a specified phenomenon occurs
* within a specified interval. The system unit for this quantity is "Hz"
* (Hertz).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Frequency extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Frequency> UNIT = SI.HERTZ;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents an illuminance. The system unit for this quantity
* is "lx" (lux).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Illuminance extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Illuminance> UNIT = SI.LUX;
}

View File

@ -0,0 +1,31 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the diffusion of momentum.
* The system unit for this quantity is "m²/s".
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Viscosity">
* Wikipedia: Viscosity</a>
*/
public interface KinematicViscosity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<KinematicViscosity> UNIT
= new ProductUnit<KinematicViscosity>(SI.METRE.pow(2).divide(SI.SECOND));
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the extent of something along its greatest
* dimension or the extent of space between two objects or places.
* The system unit for this quantity is "m" (meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Length extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Length> UNIT = SI.METRE;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a luminous flux. The system unit for this quantity
* is "lm" (lumen).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface LuminousFlux extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<LuminousFlux> UNIT = SI.LUMEN;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the luminous flux density per solid angle as
* measured in a given direction relative to the emitting source.
* The system unit for this quantity is "cd" (candela).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface LuminousIntensity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<LuminousIntensity> UNIT = SI.CANDELA;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a magnetic flux. The system unit for this quantity
* is "Wb" (Weber).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface MagneticFlux extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<MagneticFlux> UNIT = SI.WEBER;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a magnetic flux density. The system unit for this
* quantity is "T" (Tesla).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface MagneticFluxDensity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<MagneticFluxDensity> UNIT = SI.TESLA;
}

View File

@ -0,0 +1,29 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the measure of the quantity of matter that a body
* or an object contains. The mass of the body is not dependent on gravity
* and therefore is different from but proportional to its weight.
* The system unit for this quantity is "kg" (kilogram).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Mass extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Mass> UNIT = SI.KILOGRAM;
}

View File

@ -0,0 +1,31 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the movement of mass per time.
* The system unit for this quantity is "kg/s" (kilogram per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Mass_flow_rate">
* Wikipedia: Mass Flow Rate</a>
*/
public interface MassFlowRate extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
@SuppressWarnings("unchecked")
public final static Unit<MassFlowRate> UNIT
= (Unit<MassFlowRate>) SI.KILOGRAM.divide(SI.SECOND);
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the rate at which work is done. The system unit
* for this quantity is "W" (Watt).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Power extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Power> UNIT = SI.WATT;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a force applied uniformly over a surface.
* The system unit for this quantity is "Pa" (Pascal).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Pressure extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Pressure> UNIT = SI.PASCAL;
}

View File

@ -0,0 +1,31 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
/**
* <p> This interface represents any type of quantitative properties or
* attributes of thing. Mass, time, distance, heat, and angular separation
* are among the familiar examples of quantitative properties.</p>
*
* <p> Distinct quantities have usually different physical dimensions; although
* it is not required nor necessary, for example {@link Torque} and
* {@link Energy} have same dimension but are of different nature
* (vector for torque, scalar for energy).</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.0, February 25, 2007
* @see <a href="http://en.wikipedia.org/wiki/Quantity">Wikipedia: Quantity</a>
* @see <a href="http://en.wikipedia.org/wiki/Dimensional_analysis">
* Wikipedia: Dimensional Analysis</a>
*/
public interface Quantity {
// No method - Tagging interface.
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the amount of energy deposited per unit of
* mass. The system unit for this quantity is "Gy" (Gray).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface RadiationDoseAbsorbed extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<RadiationDoseAbsorbed> UNIT = SI.GRAY;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the effective (or "equivalent") dose of radiation
* received by a human or some other living organism. The system unit for
* this quantity is "Sv" (Sievert).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface RadiationDoseEffective extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<RadiationDoseEffective> UNIT = SI.SIEVERT;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a radioactive activity. The system unit for
* this quantity is "Bq" (Becquerel).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface RadioactiveActivity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<RadioactiveActivity> UNIT = SI.BECQUEREL;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the angle formed by three or more planes intersecting
* at a common point. The system unit for this quantity is "sr" (steradian).
* This quantity is dimensionless.
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface SolidAngle extends Dimensionless {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<SolidAngle> UNIT = SI.STERADIAN;
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This class represents the degree of hotness or coldness of a body or
* an environment. The system unit for this quantity is "K" (Kelvin).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Temperature extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Temperature> UNIT = SI.KELVIN;
}

View File

@ -0,0 +1,34 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the moment of a force. The system unit for this
* quantity is "N·m" (Newton-Meter).
*
* <p> Note: The Newton-metre ("N·m") is also a way of exressing a Joule (unit
* of energy). However, torque is not energy. So, to avoid confusion, we
* will use the units "N·m" for torque and not "J". This distinction occurs
* due to the scalar nature of energy and the vector nature of torque.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Torque extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Torque> UNIT =
new ProductUnit<Torque>(SI.NEWTON.times(SI.METRE));
}

View File

@ -0,0 +1,27 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a distance traveled divided by the time of travel.
* The system unit for this quantity is "m/s" (meter per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Velocity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Velocity> UNIT = SI.METRES_PER_SECOND;
}

View File

@ -0,0 +1,28 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the amount of space occupied by a three-dimensional
* object or region of space, expressed in cubic units. The system unit for
* this quantity is "" (cubic meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface Volume extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<Volume> UNIT = SI.CUBIC_METRE;
}

View File

@ -0,0 +1,30 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.ProductUnit;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents a mass per unit volume of a substance under
* specified conditions of pressure and temperature. The system unit for
* this quantity is "kg/m³" (kilogram per cubic meter).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 1.0, January 14, 2006
*/
public interface VolumetricDensity extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
public final static Unit<VolumetricDensity> UNIT = new ProductUnit<VolumetricDensity>(
SI.KILOGRAM.divide(SI.METRE.pow(3)));
}

View File

@ -0,0 +1,32 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.quantity;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
/**
* This interface represents the volume of fluid passing a point in a system
* per unit of time. The system unit for this quantity is "m³/s"
* (cubic meter per second).
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.0, March 2, 2006
* @see <a href="http://en.wikipedia.org/wiki/Rate_of_fluid_flow">
* Wikipedia: Volumetric Flow Rate</a>
*/
public interface VolumetricFlowRate extends Quantity {
/**
* Holds the SI unit (Système International d'Unités) for this quantity.
*/
@SuppressWarnings("unchecked")
public final static Unit<VolumetricFlowRate> UNIT
= (Unit<VolumetricFlowRate>) SI.METRE.pow(3).divide(SI.SECOND);
}

View File

@ -0,0 +1,6 @@
<body>
<p> Provides quantitative properties or attributes of thing such as
mass, time, distance, heat, and angular separation.</p>
<p> Each quantity sub-interface holds a static <code>UNIT</code> field
holding the standard unit for the quantity.</p>
</body>

View File

@ -0,0 +1,126 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents the units used in expressions to distinguish
* between quantities of a different nature but of the same dimensions.</p>
*
* <p> Instances of this class are created through the
* {@link Unit#alternate(String)} method.</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 4.2, August 26, 2007
*/
public final class AlternateUnit<Q extends Quantity> extends DerivedUnit<Q> {
/**
* Holds the symbol.
*/
private final String _symbol;
/**
* Holds the parent unit (a system unit).
*/
private final Unit<?> _parent;
/**
* Creates an alternate unit for the specified unit identified by the
* specified symbol.
*
* @param symbol the symbol for this alternate unit.
* @param parent the system unit from which this alternate unit is
* derived.
* @throws UnsupportedOperationException if the source is not
* a standard unit.
* @throws IllegalArgumentException if the specified symbol is
* associated to a different unit.
*/
AlternateUnit(String symbol, Unit<?> parent) {
if (!parent.isStandardUnit())
throw new UnsupportedOperationException(this
+ " is not a standard unit");
_symbol = symbol;
_parent = parent;
// Checks if the symbol is associated to a different unit.
synchronized (Unit.SYMBOL_TO_UNIT) {
Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
if (unit == null) {
Unit.SYMBOL_TO_UNIT.put(symbol, this);
return;
}
if (unit instanceof AlternateUnit) {
AlternateUnit<?> existingUnit = (AlternateUnit<?>) unit;
if (symbol.equals(existingUnit._symbol)
&& _parent.equals(existingUnit._parent))
return; // OK, same unit.
}
throw new IllegalArgumentException("Symbol " + symbol
+ " is associated to a different unit");
}
}
/**
* Returns the symbol for this alternate unit.
*
* @return this alternate unit symbol.
*/
public final String getSymbol() {
return _symbol;
}
/**
* Returns the parent unit from which this alternate unit is derived
* (a system unit itself).
*
* @return the parent of the alternate unit.
*/
@SuppressWarnings("unchecked")
public final Unit<? super Q> getParent() {
return (Unit<? super Q>) _parent;
}
@Override
public final Unit<? super Q> getStandardUnit() {
return this;
}
@Override
public final UnitConverter toStandardUnit() {
return UnitConverter.IDENTITY;
}
/**
* Indicates if this alternate unit is considered equals to the specified
* object (both are alternate units with equal symbol, equal base units
* and equal converter to base units).
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
if (!(that instanceof AlternateUnit))
return false;
AlternateUnit<?> thatUnit = (AlternateUnit<?>) that;
return this._symbol.equals(thatUnit._symbol); // Symbols are unique.
}
// Implements abstract method.
public int hashCode() {
return _symbol.hashCode();
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,112 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents the building blocks on top of which all others
* units are created. Base units are typically dimensionally independent.
* The actual unit dimension is determinated by the current
* {@link Dimension.Model model}. For example using the {@link
* Dimension.Model#STANDARD standard} model, {@link SI#CANDELA}
* has the dimension of {@link SI#WATT watt}:[code]
* // Standard model.
* BaseUnit<Length> METER = new BaseUnit<Length>("m");
* BaseUnit<LuminousIntensity> CANDELA = new BaseUnit<LuminousIntensity>("cd");
* System.out.println(METER.getDimension());
* System.out.println(CANDELA.getDimension());
*
* > [L]
* > [L]²·[M]/[T]³
* [/code]</p>
* <p> This class represents the "standard base units" which includes SI base
* units and possibly others user-defined base units. It does not represent
* the base units of any specific {@link SystemOfUnits} (they would have
* be base units accross all possible systems otherwise).</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
* @see <a href="http://en.wikipedia.org/wiki/SI_base_unit">
* Wikipedia: SI base unit</a>
*/
public class BaseUnit<Q extends Quantity> extends Unit<Q> {
/**
* Holds the symbol.
*/
private final String _symbol;
/**
* Creates a base unit having the specified symbol.
*
* @param symbol the symbol of this base unit.
* @throws IllegalArgumentException if the specified symbol is
* associated to a different unit.
*/
public BaseUnit(String symbol) {
_symbol = symbol;
// Checks if the symbol is associated to a different unit.
synchronized (Unit.SYMBOL_TO_UNIT) {
Unit<?> unit = Unit.SYMBOL_TO_UNIT.get(symbol);
if (unit == null) {
Unit.SYMBOL_TO_UNIT.put(symbol, this);
return;
}
if (!(unit instanceof BaseUnit))
throw new IllegalArgumentException("Symbol " + symbol
+ " is associated to a different unit");
}
}
/**
* Returns the unique symbol for this base unit.
*
* @return this base unit symbol.
*/
public final String getSymbol() {
return _symbol;
}
/**
* Indicates if this base unit is considered equals to the specified
* object (both are base units with equal symbol, standard dimension and
* standard transform).
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
if (!(that instanceof BaseUnit))
return false;
BaseUnit<?> thatUnit = (BaseUnit<?>) that;
return this._symbol.equals(thatUnit._symbol);
}
@Override
public int hashCode() {
return _symbol.hashCode();
}
@Override
public Unit<? super Q> getStandardUnit() {
return this;
}
@Override
public UnitConverter toStandardUnit() {
return UnitConverter.IDENTITY;
}
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,109 @@
/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javax.measure.unit;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Quantity;
/**
* <p> This class represents the multi-radix units (such as "hour:min:sec").
* Instances of this class are created using the {@link Unit#compound
* Unit.compound} method.</p>
*
* <p> Examples of compound units:[code]
* Unit<Duration> HOUR_MINUTE_SECOND = HOUR.compound(MINUTE).compound(SECOND);
* Unit<Angle> DEGREE_MINUTE_ANGLE = DEGREE_ANGLE.compound(MINUTE_ANGLE);
* [/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 3.1, April 22, 2006
*/
public final class CompoundUnit<Q extends Quantity> extends DerivedUnit<Q> {
/**
* Holds the higher unit.
*/
private final Unit<Q> _high;
/**
* Holds the lower unit.
*/
private final Unit<Q> _low;
/**
* Creates a compound unit from the specified units.
*
* @param high the high unit.
* @param low the lower unit(s)
* @throws IllegalArgumentException if both units do not the same system
* unit.
*/
CompoundUnit(Unit<Q> high, Unit<Q> low) {
if (!high.getStandardUnit().equals(low.getStandardUnit()))
throw new IllegalArgumentException(
"Both units do not have the same system unit");
_high = high;
_low = low;
}
/**
* Returns the lower unit of this compound unit.
*
* @return the lower unit.
*/
public Unit<Q> getLower() {
return _low;
}
/**
* Returns the higher unit of this compound unit.
*
* @return the higher unit.
*/
public Unit<Q> getHigher() {
return _high;
}
/**
* Indicates if this compound unit is considered equals to the specified
* object (both are compound units with same composing units in the
* same order).
*
* @param that the object to compare for equality.
* @return <code>true</code> if <code>this</code> and <code>that</code>
* are considered equals; <code>false</code>otherwise.
*/
public boolean equals(Object that) {
if (this == that)
return true;
if (!(that instanceof CompoundUnit))
return false;
CompoundUnit<?> thatUnit = (CompoundUnit<?>) that;
return this._high.equals(thatUnit._high)
&& this._low.equals(thatUnit._low);
}
@Override
public int hashCode() {
return _high.hashCode() ^ _low.hashCode();
}
@Override
public Unit<? super Q> getStandardUnit() {
return _low.getStandardUnit();
}
@Override
public UnitConverter toStandardUnit() {
return _low.toStandardUnit();
}
private static final long serialVersionUID = 1L;
}

Some files were not shown because too many files have changed in this diff Show More