org.simantics.compressions;bundle-version="1.0.0",
org.simantics.backup,
org.eclipse.core.runtime;bundle-version="3.11.1",
- org.simantics.db.procore
+ org.simantics.db.procore,
+ org.slf4j.api;bundle-version="1.7.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.simantics.acorn.internal.Activator
import org.simantics.db.service.ClusterUID;
import org.simantics.utils.threads.logger.ITask;
import org.simantics.utils.threads.logger.ThreadLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ClusterManager {
+
+ final static Logger LOGGER = LoggerFactory.getLogger(ClusterManager.class);
private ArrayList<String> currentChanges = new ArrayList<String>();
return false;
}
- System.err.println("makeSnapshot");
+ LOGGER.info("makeSnapshot");
// Schedule writing of all data to disk
refreshHeadState();
amountOfFiles = countFiles(workingDirectory);
- System.err.println(" -finished: amount of files is " + amountOfFiles);
+ LOGGER.info(" -finished: amount of files is {}", amountOfFiles);
workingDirectory = dbFolder.resolve(Integer.toString(mainState.headDir));
if (!Files.exists(workingDirectory)) {
columnAccessor = new GEColumnAccessor(this);
IDataProvider dataProvider = new ListDataProvider<TreeNode>(list, columnAccessor);
-
- int defaultFontSize = 12;
- int height = (int)Math.ceil(((double)(defaultFontSize))*getDisplayScale()) + DataLayer.DEFAULT_ROW_HEIGHT-defaultFontSize;
- dataLayer = new DataLayer(dataProvider, DataLayer.DEFAULT_COLUMN_WIDTH, height);
+
+// FIXME: NatTable 1.0 required help to work with custom display scaling (Windows 7 display scaling).
+// It seems that NatTable 1.4 breaks with the same code in Windows 7, so now the code is disabled.
+// More testing with different hardware is required...
+// int defaultFontSize = 12;
+// int height = (int)Math.ceil(((double)(defaultFontSize))*getDisplayScale()) + DataLayer.DEFAULT_ROW_HEIGHT-defaultFontSize;
+// dataLayer = new DataLayer(dataProvider, DataLayer.DEFAULT_COLUMN_WIDTH, height);
+ dataLayer = new DataLayer(dataProvider);
// resizable rows are unnecessary in Sulca report.
dataLayer.setRowsResizableByDefault(false);
// Column header layer
columnHeaderDataProvider = new GEColumnHeaderDataProvider(this, dataLayer);
columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
- columnHeaderDataLayer.setDefaultRowHeight(height);
+ //columnHeaderDataLayer.setDefaultRowHeight(height);
columnHeaderDataProvider.updateColumnSizes();
//ISortModel sortModel = new EcoSortModel(this, generator,dataLayer);
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.services.IDisposable;
import org.simantics.browsing.ui.GraphExplorer;
-public class DefaultExplorerSelectionListener implements ISelectionListener {
+public class DefaultExplorerSelectionListener implements ISelectionListener, IDisposable {
private static final boolean DEBUG = false;
this.filter = filter;
}
+ @Override
+ public void dispose() {
+ owner = null;
+ explorer = null;
+ filter = null;
+ }
+
@Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
// Always disregard own selections.
if (DEBUG)
System.out.println("[" + owner + "] workbench selection changed: part=" + part + ", selection=" + selection);
ISelection s = selection;
+ WorkbenchSelectionFilter filter = this.filter;
if (filter != null)
s = filter.filterSelection(part, selection);
System.out.println("** [" + owner + "] workbench selection changed: part=" + part + ", selection=" + selection);
System.out.println(" SETTING NEW SELECTION");
}
- if(!explorer.isDisposed()) {
+ GraphExplorer explorer = this.explorer;
+ if(explorer != null && !explorer.isDisposed()) {
IPostSelectionProvider selectionProvider = (IPostSelectionProvider)explorer.getAdapter(IPostSelectionProvider.class);
- selectionProvider.setSelection(selection);
+ if (selectionProvider != null) {
+ selectionProvider.setSelection(selection);
+ }
}
} else {
if (DEBUG)
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.services.IDisposable;
import org.simantics.browsing.ui.Column;
import org.simantics.browsing.ui.GraphExplorer;
import org.simantics.browsing.ui.NodeContext;
// Remember to remove the installed workbench selection listener
if (workbenchSelectionListener != null) {
getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener);
+ if (workbenchSelectionListener instanceof IDisposable)
+ ((IDisposable) workbenchSelectionListener).dispose();
workbenchSelectionListener = null;
getSite().setSelectionProvider(null);
return true;
}
- @SuppressWarnings("rawtypes")
+ @SuppressWarnings("unchecked")
@Override
- public Object getAdapter(Class adapter) {
+ public <T> T getAdapter(Class<T> adapter) {
if (GraphExplorer.class == adapter)
- return explorer;
+ return (T) explorer;
else if(ISessionContextProvider.class == adapter)
- return getSessionContextProvider();
+ return (T) getSessionContextProvider();
else if(IPropertyPage.class == adapter)
- return getPropertyPage();
+ return (T) getPropertyPage();
return super.getAdapter(adapter);
return "QueryIndex " + parameter + " " + parameter2 + " " + parameter3;
}
- @Override
- public boolean isImmutable(ReadGraph graph) throws DatabaseException {
- // TODO Auto-generated method stub
- return false;
- }
+ @Override
+ public boolean isImmutable(ReadGraph graph) throws DatabaseException {
+ return graph.isImmutable(parameter);
+ }
@Override
public int getType() {
import org.simantics.db.common.request.ObjectsWithType;
import org.simantics.db.common.request.ResourceRead;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.RequestFlags;
import org.simantics.layer0.Layer0;
public class OntologiesFromLibrary extends ResourceRead<List<Resource>> {
Layer0 L0 = Layer0.getInstance(graph);
ArrayList<Resource> result = new ArrayList<Resource>();
for(Resource r : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, L0.Library))) {
- if(graph.isInstanceOf(r, L0.Ontology))
- result.add(r);
- else
+ if(graph.isInstanceOf(r, L0.IndexRoot)) {
+ if(graph.isInstanceOf(r, L0.Ontology)) {
+ result.add(r);
+ }
+ } else {
result.addAll(graph.syncRequest(new OntologiesFromLibrary(r)));
+ }
}
return result;
}
+ @Override
+ public int getType() {
+ return RequestFlags.IMMEDIATE_UPDATE;
+ }
+
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.layer0.adapter.impl.EntityRemover;
import org.simantics.db.layer0.exception.CannotRemoveException;
import org.simantics.db.layer0.internal.SimanticsInternal;
-import org.simantics.utils.strings.AlphanumComparator;
import org.simantics.utils.strings.EString;
/**
public static boolean canRemove(ReadGraph graph, Resource resource) throws DatabaseException {
Remover remover = RemoverUtil.getPossibleRemover(graph, resource);
if (remover != null) {
- String problem = remover.canRemove(graph, new HashMap<Object, Object>(4));
+ String problem = remover.canRemove(graph, new HashMap<>(4));
if (problem != null) return false;
}
return true;
public static String testRemoval(ReadGraph graph, final Collection<Resource> rs, List<Remover> removers) throws DatabaseException {
if (removers == null)
- removers = new ArrayList<Remover>(rs.size());
+ removers = new ArrayList<>(rs.size());
for (Resource r : rs) {
Remover remover = graph.getPossibleAdapter(r, Remover.class);
removers.add(remover);
}
- Map<Object, Object> aux = new HashMap<Object, Object>();
- List<String> errors = new ArrayList<String>(2);
+ Map<Object, Object> aux = new HashMap<>();
+ List<String> errors = new ArrayList<>(2);
for (Remover remover : removers) {
String error = remover.canRemove(graph, aux);
if (error != null)
graph.addMetadata(cm.add("Removing " + r + "."));
}
- List<Remover> removers = new ArrayList<Remover>(rs.size());
+ List<Remover> removers = new ArrayList<>(rs.size());
String error = testRemoval(graph, rs, removers);
if (error != null)
throw new CannotRemoveException(error);
@Override
public Boolean perform(WriteGraph graph) throws DatabaseException {
graph.markUndoPoint();
- // 1. make sure that all resources are of the same type
- Collection<Resource> principalTypes = null;
- for (Resource r : rs) {
- Collection<Resource> pts = graph.getPrincipalTypes(r);
- if (principalTypes == null) {
- principalTypes = pts;
- } else if (!principalTypes.equals(pts)) {
- //return false;
- StringBuilder sb = new StringBuilder();
- sb.append("Removing resources of different types at the same time is currently not supported.\n\nThe selection contained resources of the following types:\n");
- Set<Resource> differentTypes = new HashSet<Resource>();
- Set<String> typeNames = new TreeSet<String>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);
- for (Resource t : rs)
- differentTypes.addAll(graph.getPrincipalTypes(t));
- for (Resource t : differentTypes)
- typeNames.add(NameUtils.getSafeName(graph, t));
- for (String typeName : typeNames)
- sb.append("\t").append(typeName).append("\n");
- throw new CannotRemoveException(sb.toString());
- }
- }
- List<Remover> removers = new ArrayList<Remover>();
- Map<Remover, String> removedResources = new HashMap<Remover, String>();
+ List<Remover> removers = new ArrayList<>();
+ Map<Remover, String> removedResources = new HashMap<>();
for (Resource r : rs) {
Remover remover = graph.getPossibleAdapter(r, Remover.class);
if (remover != null) {
}
}
- Map<Object, Object> aux = new HashMap<Object, Object>();
- List<String> errors = new ArrayList<String>(removers.size());
+ Map<Object, Object> aux = new HashMap<>();
+ List<String> errors = new ArrayList<>(removers.size());
for (Remover remover : removers) {
String error = remover.canRemove(graph, aux);
if (error != null)
Require-Bundle: org.simantics.graph;bundle-version="1.0.0";visibility:=reexport,
org.simantics.db.common;bundle-version="0.8.0",
gnu.trove3;bundle-version="3.0.3",
- org.simantics.layer0;bundle-version="1.0.0"
+ org.simantics.layer0;bundle-version="1.0.0",
+ org.slf4j.api;bundle-version="1.7.2"
Export-Package: org.simantics.graph.db,
org.simantics.graph.db.old
Bundle-Vendor: VTT Technical Research Centre of Finland
import org.simantics.graph.representation.TransferableGraph1;
import org.simantics.graph.representation.Value;
import org.simantics.utils.datastructures.BinaryFunction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.map.hash.TObjectIntHashMap;
public class TransferableGraphs {
+ final static Logger LOGGER = LoggerFactory.getLogger(TransferableGraphs.class);
public static long[] importGraph(Session session, Object tg, IImportAdvisor advisor) throws DatabaseException, TransferableGraphException {
if (tg instanceof TransferableGraph1)
});
long end = System.nanoTime();
- System.err.println("Wrote transferable graph in " + 1e-9*(end-start) + " seconds.");
+ LOGGER.info("Wrote transferable graph in {} seconds.", 1e-9*(end-start));
}
public static TransferableGraph1 create(ReadGraph graph, TransferableGraphSource source) throws DatabaseException {
return;
// Add command to command history
- commandHistory.add(command);
- if(commandHistory.size() > COMMAND_HISTORY_SIZE*2)
- commandHistory = new ArrayList<String>(
- commandHistory.subList(COMMAND_HISTORY_SIZE, COMMAND_HISTORY_SIZE*2));
+ if(commandHistory.isEmpty() || !commandHistory.get(commandHistory.size()-1).equals(command)) {
+ commandHistory.add(command);
+ if(commandHistory.size() > COMMAND_HISTORY_SIZE*2)
+ commandHistory = new ArrayList<String>(
+ commandHistory.subList(COMMAND_HISTORY_SIZE, COMMAND_HISTORY_SIZE*2));
+ }
commandHistoryPos = commandHistory.size();
// Print it into output area
}
@Override
- public void addSubprocess(String name) {
+ public void addSubprocess(String name, String subprocessType) {
ensureSubprocess(name);
}
configurationByUid.clear();
pendingRemoval.clear();
}
+
+ public boolean hasPendingRemovals() {
+ return !pendingRemoval.isEmpty();
+ }
}
new THashMap<String, ConnectionUpdateRule<T>>();
public boolean isUserComponent;
public boolean isComposite;
+ public String subprocessType;
public ModuleUpdaterBase(String moduleType) {
this.moduleType = moduleType;
public void remove(int id);
- public void addSubprocess(String name);
+ public void addSubprocess(String name, String subprocessType);
public void includeSubprocess(String parentName, String subprocessName);
public <T> T getConcreteSolver();
package org.simantics.structural.synchronization.base;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import org.simantics.structural.synchronization.protocol.SynchronizationEventHandler;
import org.simantics.structural.synchronization.protocol.SynchronizationException;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
/**
* Handles synchronization events by updating the simulator designated by the
* provided {@link Solver} instance.
parentSolverComponentName,
getSubprocessName(name, properties));
try {
- solver.addSubprocess(subprocessName);
+ solver.addSubprocess(subprocessName, updater.subprocessType);
} catch(Exception e) {
reportProblem("Exception while adding subprocess.", e);
}
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.variable.Variable;
+import gnu.trove.map.hash.THashMap;
+
/**
* Utility for updating UIDs in the given component to correspond
* the RVIs of the given variable. This operation is needed when
* the mapping is part of a model that is imported to a new database
* and resource ids have been changed.
- *
+ *
* @author Hannu Niemistö
* @author Tuukka Lehtonen
*/
void componentsDone(int components, int componentCount);
}
+ private THashMap<String, String> oldToNewUids;
private IProgressMonitor monitor;
private ComponentUpdateProgressMonitor componentMonitor;
private ReadGraph graph;
- private int componentCount;
+ private int componentCount;
private int counter;
private UpdateComponentUids(IProgressMonitor monitor, ReadGraph graph, int componentCount) {
this.componentMonitor = monitor instanceof ComponentUpdateProgressMonitor ? (ComponentUpdateProgressMonitor) monitor : null;
this.graph = graph;
this.componentCount = componentCount;
+ this.oldToNewUids = new THashMap<>(componentCount);
}
private void update(T component, Variable variable) throws DatabaseException {
- component.uid = variable.getRVI(graph).toString();
+ String newUid = variable.getRVI(graph).toString();
+ oldToNewUids.put(component.uid, newUid);
+ component.uid = newUid;
// Handle progress monitoring and cancellation
counter++;
}
}
- public static <T extends ComponentBase<T>> void update(ReadGraph graph, T component, Variable variable) throws DatabaseException {
- update(null, graph, component, variable);
+ public static <T extends ComponentBase<T>> THashMap<String, String> update(ReadGraph graph, T component, Variable variable) throws DatabaseException {
+ return update(null, graph, component, variable);
}
- public static <T extends ComponentBase<T>> void update(IProgressMonitor monitor, ReadGraph graph, T component, Variable variable) throws DatabaseException {
- new UpdateComponentUids<T>(monitor, graph, countComponents(component)).update(component, variable);
+ public static <T extends ComponentBase<T>> THashMap<String, String> update(IProgressMonitor monitor, ReadGraph graph, T component, Variable variable) throws DatabaseException {
+ UpdateComponentUids<T> updateComponentUids = new UpdateComponentUids<T>(monitor, graph, countComponents(component));
+ updateComponentUids.update(component, variable);
+ return updateComponentUids.oldToNewUids;
}
public static <T extends ComponentBase<T>> int countComponents(T component) {
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
*/
- @SuppressWarnings("rawtypes")
@Override
- public Object getAdapter(Class adapter) {
+ public <T> T getAdapter(Class<T> adapter) {
//System.out.println("[ResourceEditorInput] getAdapter: " + adapter.getName());
return null;
}
System.out.println("update(" + this + ")");
try {
- assertExists(g);
+ //assertExists(g);
name = g.syncRequest(new TitleRequest(editorID, this));
if (name == null)
import org.simantics.db.Session;
import org.simantics.db.common.procedure.adapter.ListenerAdapter;
import org.simantics.db.common.request.ParametrizedRead;
-import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.event.ChangeEvent;
import org.simantics.db.event.ChangeListener;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.management.ISessionContext;
import org.simantics.db.management.ISessionContextProvider;
-import org.simantics.db.request.Read;
import org.simantics.db.service.GraphChangeListenerSupport;
import org.simantics.ui.SimanticsUI;
import org.simantics.utils.datastructures.map.Tuple;
import org.simantics.utils.ui.ExceptionUtils;
import org.simantics.utils.ui.SWTUtils;
import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A helper class for easing the attachment of a Simantics database session to
*/
public class ResourceEditorSupport implements IAdaptable, ChangeListener {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ResourceEditorSupport.class);
+ private static final boolean DEBUG = false;
+
private IEditorPart editorPart;
private ChangeListener editorPartChangeListener;
return;
inputListener = new InputListener();
- getSession().asyncRequest(validationRequest(editorPart), inputListener);
+ getSession().asyncRequest(new ValidationRequest(), inputListener);
}
public synchronized void deactivateValidation() {
if (inputListener == null)
return;
inputListener.dispose();
+ inputListener = null;
}
public ISessionContext getSessionContext() {
return session;
}
- @SuppressWarnings("rawtypes")
+ @SuppressWarnings("unchecked")
@Override
- public Object getAdapter(Class adapter) {
+ public <T> T getAdapter(Class<T> adapter) {
if (adapter == ISessionContext.class)
- return getSessionContext();
+ return (T) getSessionContext();
if (adapter == Session.class)
- return getSession();
+ return (T) getSession();
return null;
}
@Override
public void graphChanged(ChangeEvent e) throws DatabaseException {
- //System.out.println(this + ": graph change: " + e);
// Only forward the update to the editor if the input is still valid and
// the editor implements ChangeListener
if (editorPart instanceof ChangeListener)
}
/**
- * @param input
- * @return a read request that returns <code>true</code> for valid inputs
- * and <code>false</code> for non-existent or invalid inputs.
+ * A read request that returns an {@link Evaluation} of the current state of
+ * <code>editorPart</code>.
+ *
+ * <p>
+ * This request class is not static but has no parameters that could get
+ * stuck in the database client caches. UniqueRead does not need arguments
+ * and without custom hashCode/equals implementations, each instance of this
+ * request is a different one. This is exactly the behaviour we want in this
+ * case.
*/
- private Read<Evaluation> validationRequest(IEditorPart editorPart) {
- return new UnaryRead<IEditorPart, Evaluation>(editorPart) {
- @Override
- public Evaluation perform(ReadGraph graph) throws DatabaseException {
- IEditorInput input = parameter.getEditorInput();
- IResourceEditorInput resourceInput = getResourceInput(parameter);
-
- //System.out.println(ResourceEditorSupport.this + ": checking input " + input);
-
- boolean exists = true;
- boolean valid = true;
- if (resourceInput != null) {
- exists = resourceInput.exists(graph);
- if (exists && inputValidator != null) {
- valid = graph.syncRequest(inputValidator.get(resourceInput));
- }
- } else {
- exists = input.exists();
+ private class ValidationRequest extends UniqueRead<Evaluation> {
+ @Override
+ public Evaluation perform(ReadGraph graph) throws DatabaseException {
+ IEditorPart part = editorPart;
+ if (part == null)
+ return new Evaluation(null, null, InputState.INVALID, "", "");
+
+ IEditorInput input = part.getEditorInput();
+ IResourceEditorInput resourceInput = getResourceInput(part);
+
+ if (DEBUG)
+ LOGGER.trace("ValidationRequest: checking input " + input);
+
+ boolean exists = true;
+ boolean valid = true;
+ if (resourceInput != null) {
+ exists = resourceInput.exists(graph);
+ if (exists && inputValidator != null) {
+ valid = graph.syncRequest(inputValidator.get(resourceInput));
}
+ } else {
+ exists = input.exists();
+ }
- InputState state = InputState.parse(exists, valid);
- if (state == InputState.VALID) {
- // Make sure any cached data in the editor input is up-to-date.
+ InputState state = InputState.parse(exists, valid);
+ if (state == InputState.VALID) {
+ // Make sure any cached data in the editor input is up-to-date.
+ if (resourceInput != null)
resourceInput.update(graph);
- }
-
- Evaluation eval = new Evaluation(parameter, input, state, input.getName(), input.getToolTipText());
- //System.out.println(ResourceEditorSupport.this + ": validation evaluation: " + eval);
- return eval;
}
- };
+
+ Evaluation eval = new Evaluation(part, input, state, input.getName(), input.getToolTipText());
+ if (DEBUG)
+ LOGGER.trace("ValidationRequest: evaluation result: " + eval);
+ return eval;
+ }
}
- private class InputListener extends ListenerAdapter<Evaluation> {
+ private static class InputListener extends ListenerAdapter<Evaluation> {
private boolean disposed = false;
@Override
public void execute(Evaluation evaluation) {
- //System.out.println("InputListener: " + evaluation);
+ if (DEBUG)
+ LOGGER.trace("InputListener: " + evaluation);
switch (evaluation.getInputState()) {
case VALID:
break;
-
case INVALID:
case NON_EXISTENT:
scheduleEditorClose(evaluation.getEditorPart());
@Override
public boolean isDisposed() {
- return disposed || ResourceEditorSupport.this.isDisposed();
+ return disposed;
}
}
- private void scheduleEditorClose(final IEditorPart editorPart) {
- SWTUtils.asyncExec(editorPart.getSite().getShell(), new Runnable() {
- @Override
- public void run() {
- // Don't have to check isDisposed since closeEditor
- // will ignore already closed editor parts.
- WorkbenchUtils.closeEditor(editorPart, false);
- }
+ private static void scheduleEditorClose(IEditorPart editorPart) {
+ SWTUtils.asyncExec(editorPart.getSite().getShell(), () -> {
+ // Don't have to check isDisposed since closeEditor
+ // will ignore already closed editor parts.
+ WorkbenchUtils.closeEditor(editorPart, false);
});
}
GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
label.setLayoutData(data);
- label.setFont(parent.getFont());
}
texts[i] = new Text(composite, SWT.SINGLE | SWT.BORDER);
texts[i].setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
}
public static Format significantDigitFormat(int withSignificantDigits) {
- return significantDigitFormat(withSignificantDigits, false);
+ return significantDigitFormat(Locale.getDefault(Locale.Category.FORMAT), withSignificantDigits);
+ }
+
+ public static Format significantDigitFormat(Locale locale, int withSignificantDigits) {
+ return significantDigitFormat(locale, withSignificantDigits, false);
}
public static Format significantDigitFormat(int withSignificantDigits, boolean stripTrailingZeros) {
+ return significantDigitFormat(Locale.getDefault(Locale.Category.FORMAT), withSignificantDigits, stripTrailingZeros);
+ }
+
+ public static Format significantDigitFormat(Locale locale, int withSignificantDigits, boolean stripTrailingZeros) {
if (withSignificantDigits < 1)
throw new IllegalArgumentException("withSignificantDigits must be > 0, got " + withSignificantDigits);
StringBuilder sb = new StringBuilder(withSignificantDigits + 3);
for (int i = 0; i < withSignificantDigits-1; i++)
sb.append("#");
sb.append("E0");
- NumberFormat low = new DecimalFormat(sb.toString());
+ NumberFormat low = new DecimalFormat(sb.toString(), DecimalFormatSymbols.getInstance(locale));
low.setGroupingUsed(false);
- NumberFormat hi = new SignificantDigitFormat(withSignificantDigits, stripTrailingZeros);
+ NumberFormat hi = new SignificantDigitFormat(locale, withSignificantDigits, stripTrailingZeros);
Format format = new SwitchFormat(0.1, 1, low, hi, hi);
return format;
}
private boolean fixDecimalSeparator;
private char decimalSeparator;
- public SignificantDigitFormat(int digits, boolean stripTrailingZeros) {
+ public SignificantDigitFormat(Locale locale, int digits, boolean stripTrailingZeros) {
this.mc = new MathContext(digits);
this.stripTrailingZeros = stripTrailingZeros;
- DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
+ DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
decimalSeparator = symbols.getDecimalSeparator();
// BigDecimal always formats doubles with '.' as decimal separator.
if (decimalSeparator != '.')