mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 19:14:55 +00:00
Merge remote-tracking branch 'upstream/develop' into 5130_exportCSV
This commit is contained in:
commit
29bdc2ee52
@ -45,6 +45,9 @@
|
|||||||
|
|
||||||
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
||||||
<dependency conf="core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.3"/>
|
<dependency conf="core->default" org="net.htmlparser.jericho" name="jericho-html" rev="3.3"/>
|
||||||
|
<dependency org="com.squareup.okhttp" name="okhttp" rev="2.7.5"/>
|
||||||
|
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
|
||||||
|
<dependency org="javax.ws.rs" name="javax.ws.rs-api" rev="2.0"/>
|
||||||
<override org="jakarta.ws.rs" module="jakarta.ws.rs-api" rev="2.1.5"/>
|
<override org="jakarta.ws.rs" module="jakarta.ws.rs-api" rev="2.1.5"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</ivy-module>
|
</ivy-module>
|
||||||
|
@ -111,6 +111,10 @@ file.reference.grpc-context-1.19.0.jar=release/modules/ext/grpc-context-1.19.0.j
|
|||||||
file.reference.opencensus-api-0.19.2.jar=release/modules/ext/opencensus-api-0.19.2.jar
|
file.reference.opencensus-api-0.19.2.jar=release/modules/ext/opencensus-api-0.19.2.jar
|
||||||
file.reference.opencensus-contrib-http-util-0.19.2.jar=release/modules/ext/opencensus-contrib-http-util-0.19.2.jar
|
file.reference.opencensus-contrib-http-util-0.19.2.jar=release/modules/ext/opencensus-contrib-http-util-0.19.2.jar
|
||||||
file.reference.threetenbp-1.3.3.jar=release/modules/ext/threetenbp-1.3.3.jar
|
file.reference.threetenbp-1.3.3.jar=release/modules/ext/threetenbp-1.3.3.jar
|
||||||
|
file.reference.okhttp-2.7.5-javadoc.jar=release/modules/ext/okhttp-2.7.5-javadoc.jar
|
||||||
|
file.reference.okhttp-2.7.5-sources.jar=release/modules/ext/okhttp-2.7.5-sources.jar
|
||||||
|
file.reference.okhttp-2.7.5.jar=release/modules/ext/okhttp-2.7.5.jar
|
||||||
|
file.reference.okio-1.6.0.jar=release/modules/ext/okio-1.6.0.jar
|
||||||
javac.source=1.8
|
javac.source=1.8
|
||||||
javac.compilerargs=-Xlint -Xlint:-serial
|
javac.compilerargs=-Xlint -Xlint:-serial
|
||||||
license.file=../LICENSE-2.0.txt
|
license.file=../LICENSE-2.0.txt
|
||||||
|
@ -773,6 +773,14 @@
|
|||||||
<runtime-relative-path>ext/google-api-services-translate-v2-rev20170525-1.27.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/google-api-services-translate-v2-rev20170525-1.27.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release/modules/ext/google-api-services-translate-v2-rev20170525-1.27.0.jar</binary-origin>
|
<binary-origin>release/modules/ext/google-api-services-translate-v2-rev20170525-1.27.0.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/okhttp-2.7.5.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/okhttp-2.7.5.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/okio-1.6.0.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/okio-1.6.0.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
</data>
|
</data>
|
||||||
</configuration>
|
</configuration>
|
||||||
</project>
|
</project>
|
||||||
|
@ -66,6 +66,7 @@ DataSourceSummaryDialog.window.title=Data Sources Summary
|
|||||||
DataSourceSummaryNode.column.dataSourceName.header=Data Source Name
|
DataSourceSummaryNode.column.dataSourceName.header=Data Source Name
|
||||||
DataSourceSummaryNode.column.files.header=Files
|
DataSourceSummaryNode.column.files.header=Files
|
||||||
DataSourceSummaryNode.column.results.header=Results
|
DataSourceSummaryNode.column.results.header=Results
|
||||||
|
DataSourceSummaryNode.column.status.header=Ingest Status
|
||||||
DataSourceSummaryNode.column.tags.header=Tags
|
DataSourceSummaryNode.column.tags.header=Tags
|
||||||
DataSourceSummaryNode.column.type.header=Type
|
DataSourceSummaryNode.column.type.header=Type
|
||||||
DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source
|
DataSourceSummaryNode.viewDataSourceAction.text=Go to Data Source
|
||||||
|
@ -37,8 +37,10 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
|||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryNode.DataSourceSummaryEntryNode;
|
import org.sleuthkit.autopsy.casemodule.datasourcesummary.DataSourceSummaryNode.DataSourceSummaryEntryNode;
|
||||||
import static javax.swing.SwingConstants.RIGHT;
|
import static javax.swing.SwingConstants.RIGHT;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
@ -50,9 +52,10 @@ final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerMana
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceBrowser.class.getName());
|
private static final Logger logger = Logger.getLogger(DataSourceBrowser.class.getName());
|
||||||
private static final int COUNT_COLUMN_WIDTH = 25;
|
private static final int COUNT_COLUMN_WIDTH = 20;
|
||||||
private static final int USAGE_COLUMN_WIDTH = 120;
|
private static final int INGEST_STATUS_WIDTH = 50;
|
||||||
private static final int DATA_SOURCE_COLUMN_WIDTH = 325;
|
private static final int USAGE_COLUMN_WIDTH = 110;
|
||||||
|
private static final int DATA_SOURCE_COLUMN_WIDTH = 280;
|
||||||
private final Outline outline;
|
private final Outline outline;
|
||||||
private final org.openide.explorer.view.OutlineView outlineView;
|
private final org.openide.explorer.view.OutlineView outlineView;
|
||||||
private final ExplorerManager explorerManager;
|
private final ExplorerManager explorerManager;
|
||||||
@ -69,6 +72,7 @@ final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerMana
|
|||||||
outlineView = new org.openide.explorer.view.OutlineView();
|
outlineView = new org.openide.explorer.view.OutlineView();
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
outlineView.setPropertyColumns(
|
outlineView.setPropertyColumns(
|
||||||
|
Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(),
|
||||||
Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(),
|
Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(),
|
||||||
Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(),
|
Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(),
|
||||||
Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(),
|
Bundle.DataSourceSummaryNode_column_results_header(), Bundle.DataSourceSummaryNode_column_results_header(),
|
||||||
@ -90,6 +94,8 @@ final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerMana
|
|||||||
column.setPreferredWidth(COUNT_COLUMN_WIDTH);
|
column.setPreferredWidth(COUNT_COLUMN_WIDTH);
|
||||||
} else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_type_header())) {
|
} else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_type_header())) {
|
||||||
column.setPreferredWidth(USAGE_COLUMN_WIDTH);
|
column.setPreferredWidth(USAGE_COLUMN_WIDTH);
|
||||||
|
} else if (column.getHeaderValue().toString().equals(Bundle.DataSourceSummaryNode_column_status_header())) {
|
||||||
|
column.setPreferredWidth(INGEST_STATUS_WIDTH);
|
||||||
} else {
|
} else {
|
||||||
column.setPreferredWidth(DATA_SOURCE_COLUMN_WIDTH);
|
column.setPreferredWidth(DATA_SOURCE_COLUMN_WIDTH);
|
||||||
}
|
}
|
||||||
@ -182,6 +188,47 @@ final class DataSourceBrowser extends javax.swing.JPanel implements ExplorerMana
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the DataSourceBrowser to display up to date status information for
|
||||||
|
* the data sources.
|
||||||
|
*
|
||||||
|
* @param dataSourceId the ID of the data source which should be updated
|
||||||
|
* @param newStatus the new status which the data source should have
|
||||||
|
*/
|
||||||
|
void refresh(long dataSourceId, IngestJobInfo.IngestJobStatusType newStatus) {
|
||||||
|
|
||||||
|
//attempt to update the status of any datasources that had status which was STARTED
|
||||||
|
for (DataSourceSummary summary : dataSourceSummaryList) {
|
||||||
|
if (summary.getDataSource().getId() == dataSourceId) {
|
||||||
|
summary.setIngestStatus(newStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//figure out which nodes were previously selected
|
||||||
|
Node[] selectedNodes = explorerManager.getSelectedNodes();
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
explorerManager.setRootContext(new DataSourceSummaryNode(dataSourceSummaryList));
|
||||||
|
List<Node> nodesToSelect = new ArrayList<>();
|
||||||
|
for (Node node : explorerManager.getRootContext().getChildren().getNodes()) {
|
||||||
|
if (node instanceof DataSourceSummaryEntryNode) {
|
||||||
|
//there should only be one selected node as multi-select is disabled
|
||||||
|
for (Node selectedNode : selectedNodes) {
|
||||||
|
if (((DataSourceSummaryEntryNode) node).getDataSource().equals(((DataSourceSummaryEntryNode) selectedNode).getDataSource())) {
|
||||||
|
nodesToSelect.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//reselect the previously selected Nodes
|
||||||
|
try {
|
||||||
|
explorerManager.setSelectedNodes(nodesToSelect.toArray(new Node[nodesToSelect.size()]));
|
||||||
|
} catch (PropertyVetoException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error selecting previously selected nodes", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
@ -18,7 +18,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.datamodel.CaseDbAccessManager;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.IngestJobInfo.IngestJobStatusType;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper object for a DataSource and the information associated with it.
|
* Wrapper object for a DataSource and the information associated with it.
|
||||||
@ -26,7 +35,10 @@ import org.sleuthkit.datamodel.DataSource;
|
|||||||
*/
|
*/
|
||||||
class DataSourceSummary {
|
class DataSourceSummary {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(DataSourceSummary.class.getName());
|
||||||
|
private static final String INGEST_JOB_STATUS_QUERY = "status_id FROM ingest_jobs WHERE obj_id=";
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
|
private IngestJobStatusType status = null;
|
||||||
private final String type;
|
private final String type;
|
||||||
private final long filesCount;
|
private final long filesCount;
|
||||||
private final long resultsCount;
|
private final long resultsCount;
|
||||||
@ -45,12 +57,26 @@ class DataSourceSummary {
|
|||||||
*/
|
*/
|
||||||
DataSourceSummary(DataSource dSource, String typeValue, Long numberOfFiles, Long numberOfResults, Long numberOfTags) {
|
DataSourceSummary(DataSource dSource, String typeValue, Long numberOfFiles, Long numberOfResults, Long numberOfTags) {
|
||||||
dataSource = dSource;
|
dataSource = dSource;
|
||||||
|
getStatusFromDatabase();
|
||||||
type = typeValue == null ? "" : typeValue;
|
type = typeValue == null ? "" : typeValue;
|
||||||
filesCount = numberOfFiles == null ? 0 : numberOfFiles;
|
filesCount = numberOfFiles == null ? 0 : numberOfFiles;
|
||||||
resultsCount = numberOfResults == null ? 0 : numberOfResults;
|
resultsCount = numberOfResults == null ? 0 : numberOfResults;
|
||||||
tagsCount = numberOfTags == null ? 0 : numberOfTags;
|
tagsCount = numberOfTags == null ? 0 : numberOfTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status of the ingest job from the case database
|
||||||
|
*/
|
||||||
|
private void getStatusFromDatabase() {
|
||||||
|
try {
|
||||||
|
IngestJobQueryCallback callback = new IngestJobQueryCallback();
|
||||||
|
Case.getCurrentCaseThrows().getSleuthkitCase().getCaseDbAccessManager().select(INGEST_JOB_STATUS_QUERY + dataSource.getId(), callback);
|
||||||
|
status = callback.getStatus();
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error getting status for data source from case database", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the DataSource
|
* Get the DataSource
|
||||||
*
|
*
|
||||||
@ -60,6 +86,16 @@ class DataSourceSummary {
|
|||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manually set the ingest job status
|
||||||
|
*
|
||||||
|
* @param ingestStatus the status which the ingest job should have
|
||||||
|
* currently, null to display empty string
|
||||||
|
*/
|
||||||
|
void setIngestStatus(IngestJobStatusType ingestStatus) {
|
||||||
|
status = ingestStatus;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of this DataSource
|
* Get the type of this DataSource
|
||||||
*
|
*
|
||||||
@ -87,6 +123,16 @@ class DataSourceSummary {
|
|||||||
return resultsCount;
|
return resultsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the IngestJobStatusType associated with this data source.
|
||||||
|
*
|
||||||
|
* @return the IngestJobStatusType associated with this data source. Can be
|
||||||
|
* null if the IngestJobStatusType is not STARTED or COMPLETED.
|
||||||
|
*/
|
||||||
|
IngestJobStatusType getIngestStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of tagged content objects in this DataSource
|
* Get the number of tagged content objects in this DataSource
|
||||||
*
|
*
|
||||||
@ -95,4 +141,40 @@ class DataSourceSummary {
|
|||||||
long getTagsCount() {
|
long getTagsCount() {
|
||||||
return tagsCount;
|
return tagsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to parse result set, getting the status to be associated with
|
||||||
|
* this data source
|
||||||
|
*/
|
||||||
|
class IngestJobQueryCallback implements CaseDbAccessManager.CaseDbAccessQueryCallback {
|
||||||
|
|
||||||
|
private IngestJobStatusType jobStatus = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(ResultSet rs) {
|
||||||
|
try {
|
||||||
|
while (rs.next()) {
|
||||||
|
IngestJobStatusType currentStatus = IngestJobStatusType.fromID(rs.getInt("status_id"));
|
||||||
|
if (currentStatus == IngestJobStatusType.COMPLETED) {
|
||||||
|
jobStatus = currentStatus;
|
||||||
|
} else if (currentStatus == IngestJobStatusType.STARTED) {
|
||||||
|
jobStatus = currentStatus;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error getting status for ingest job", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status which was determined for this callback
|
||||||
|
*
|
||||||
|
* @return the status of the data source which was queried for
|
||||||
|
*/
|
||||||
|
IngestJobStatusType getStatus() {
|
||||||
|
return jobStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,18 @@
|
|||||||
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
package org.sleuthkit.autopsy.casemodule.datasourcesummary;
|
||||||
|
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
import org.sleuthkit.autopsy.casemodule.IngestJobInfoPanel;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
|
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent;
|
||||||
|
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent.Reason;
|
||||||
import org.sleuthkit.datamodel.DataSource;
|
import org.sleuthkit.datamodel.DataSource;
|
||||||
|
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog for displaying the Data Sources Summary information
|
* Dialog for displaying the Data Sources Summary information
|
||||||
@ -38,7 +42,6 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
|||||||
private final DataSourceSummaryDetailsPanel detailsPanel;
|
private final DataSourceSummaryDetailsPanel detailsPanel;
|
||||||
private final DataSourceBrowser dataSourcesPanel;
|
private final DataSourceBrowser dataSourcesPanel;
|
||||||
private final IngestJobInfoPanel ingestHistoryPanel;
|
private final IngestJobInfoPanel ingestHistoryPanel;
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceSummaryDialog.class.getName());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form DataSourceSummaryDialog for displaying a summary of the
|
* Creates new form DataSourceSummaryDialog for displaying a summary of the
|
||||||
@ -73,6 +76,17 @@ final class DataSourceSummaryDialog extends javax.swing.JDialog implements Obser
|
|||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//add listener to refresh jobs with Started status when they complete
|
||||||
|
IngestManager.getInstance().addIngestJobEventListener((PropertyChangeEvent evt) -> {
|
||||||
|
if (evt instanceof DataSourceAnalysisCompletedEvent) {
|
||||||
|
DataSourceAnalysisCompletedEvent dsEvent = (DataSourceAnalysisCompletedEvent) evt;
|
||||||
|
if (dsEvent.getResult() == Reason.ANALYSIS_COMPLETED) {
|
||||||
|
dataSourcesPanel.refresh(dsEvent.getDataSource().getId(), IngestJobInfo.IngestJobStatusType.COMPLETED);
|
||||||
|
} else if (dsEvent.getResult() == Reason.ANALYSIS_CANCELLED) {
|
||||||
|
dataSourcesPanel.refresh(dsEvent.getDataSource().getId(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
this.pack();
|
this.pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +109,7 @@ final class DataSourceSummaryNode extends AbstractNode {
|
|||||||
static final class DataSourceSummaryEntryNode extends AbstractNode {
|
static final class DataSourceSummaryEntryNode extends AbstractNode {
|
||||||
|
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
|
private final String status;
|
||||||
private final String type;
|
private final String type;
|
||||||
private final long filesCount;
|
private final long filesCount;
|
||||||
private final long resultsCount;
|
private final long resultsCount;
|
||||||
@ -124,6 +125,7 @@ final class DataSourceSummaryNode extends AbstractNode {
|
|||||||
DataSourceSummaryEntryNode(DataSourceSummary dataSourceSummary) {
|
DataSourceSummaryEntryNode(DataSourceSummary dataSourceSummary) {
|
||||||
super(Children.LEAF);
|
super(Children.LEAF);
|
||||||
dataSource = dataSourceSummary.getDataSource();
|
dataSource = dataSourceSummary.getDataSource();
|
||||||
|
status = dataSourceSummary.getIngestStatus() == null ? "" : dataSourceSummary.getIngestStatus().getDisplayName();
|
||||||
type = dataSourceSummary.getType();
|
type = dataSourceSummary.getType();
|
||||||
filesCount = dataSourceSummary.getFilesCount();
|
filesCount = dataSourceSummary.getFilesCount();
|
||||||
resultsCount = dataSourceSummary.getResultsCount();
|
resultsCount = dataSourceSummary.getResultsCount();
|
||||||
@ -143,6 +145,7 @@ final class DataSourceSummaryNode extends AbstractNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Messages({"DataSourceSummaryNode.column.dataSourceName.header=Data Source Name",
|
@Messages({"DataSourceSummaryNode.column.dataSourceName.header=Data Source Name",
|
||||||
|
"DataSourceSummaryNode.column.status.header=Ingest Status",
|
||||||
"DataSourceSummaryNode.column.type.header=Type",
|
"DataSourceSummaryNode.column.type.header=Type",
|
||||||
"DataSourceSummaryNode.column.files.header=Files",
|
"DataSourceSummaryNode.column.files.header=Files",
|
||||||
"DataSourceSummaryNode.column.results.header=Results",
|
"DataSourceSummaryNode.column.results.header=Results",
|
||||||
@ -157,6 +160,7 @@ final class DataSourceSummaryNode extends AbstractNode {
|
|||||||
}
|
}
|
||||||
sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(),
|
sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(), Bundle.DataSourceSummaryNode_column_dataSourceName_header(),
|
||||||
dataSource));
|
dataSource));
|
||||||
|
sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), Bundle.DataSourceSummaryNode_column_status_header(), status));
|
||||||
sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(),
|
sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(), Bundle.DataSourceSummaryNode_column_type_header(),
|
||||||
type));
|
type));
|
||||||
sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(),
|
sheetSet.put(new NodeProperty<>(Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(), Bundle.DataSourceSummaryNode_column_files_header(),
|
||||||
|
@ -83,7 +83,7 @@ MediaViewImagePanel.zoomResetButton.text=Reset
|
|||||||
MediaViewImagePanel.zoomTextField.text=
|
MediaViewImagePanel.zoomTextField.text=
|
||||||
MediaViewImagePanel.rotationTextField.text=
|
MediaViewImagePanel.rotationTextField.text=
|
||||||
MediaViewImagePanel.rotateLeftButton.toolTipText=
|
MediaViewImagePanel.rotateLeftButton.toolTipText=
|
||||||
HtmlPanel.showImagesToggleButton.text=Show Images
|
HtmlPanel.showImagesToggleButton.text=Download Images
|
||||||
MediaPlayerPanel.audioSlider.toolTipText=
|
MediaPlayerPanel.audioSlider.toolTipText=
|
||||||
MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume
|
MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume
|
||||||
MediaPlayerPanel.progressLabel.text=00:00:00/00:00:00
|
MediaPlayerPanel.progressLabel.text=00:00:00/00:00:00
|
||||||
|
@ -22,7 +22,7 @@ GstVideoPanel.cannotProcFile.err=The media player cannot process this file.
|
|||||||
GstVideoPanel.noOpenCase.errMsg=No open case available.
|
GstVideoPanel.noOpenCase.errMsg=No open case available.
|
||||||
Html_text_display_error=The HTML text cannot be displayed, it may not be correctly formed HTML.
|
Html_text_display_error=The HTML text cannot be displayed, it may not be correctly formed HTML.
|
||||||
HtmlPanel_showImagesToggleButton_hide=Hide Images
|
HtmlPanel_showImagesToggleButton_hide=Hide Images
|
||||||
HtmlPanel_showImagesToggleButton_show=Show Images
|
HtmlPanel_showImagesToggleButton_show=Download Images
|
||||||
HtmlViewer_file_error=This file is missing or unreadable.
|
HtmlViewer_file_error=This file is missing or unreadable.
|
||||||
MediaFileViewer.initGst.gstException.msg=Error initializing gstreamer for audio/video viewing and frame extraction capabilities. Video and audio viewing will be disabled.
|
MediaFileViewer.initGst.gstException.msg=Error initializing gstreamer for audio/video viewing and frame extraction capabilities. Video and audio viewing will be disabled.
|
||||||
GstVideoPanel.setupVideo.infoLabel.text=Playback of deleted videos is not supported, use an external player.
|
GstVideoPanel.setupVideo.infoLabel.text=Playback of deleted videos is not supported, use an external player.
|
||||||
@ -145,7 +145,7 @@ MediaViewImagePanel.zoomResetButton.text=Reset
|
|||||||
MediaViewImagePanel.zoomTextField.text=
|
MediaViewImagePanel.zoomTextField.text=
|
||||||
MediaViewImagePanel.rotationTextField.text=
|
MediaViewImagePanel.rotationTextField.text=
|
||||||
MediaViewImagePanel.rotateLeftButton.toolTipText=
|
MediaViewImagePanel.rotateLeftButton.toolTipText=
|
||||||
HtmlPanel.showImagesToggleButton.text=Show Images
|
HtmlPanel.showImagesToggleButton.text=Download Images
|
||||||
MediaPlayerPanel.audioSlider.toolTipText=
|
MediaPlayerPanel.audioSlider.toolTipText=
|
||||||
MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume
|
MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume
|
||||||
MediaPlayerPanel.progressLabel.text=00:00:00/00:00:00
|
MediaPlayerPanel.progressLabel.text=00:00:00/00:00:00
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="showImagesToggleButton" min="-2" max="-2" attributes="0"/>
|
<Component id="showImagesToggleButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="0" pref="95" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="75" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="htmlJPanel" max="32767" attributes="0"/>
|
<Component id="htmlJPanel" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.contentviewers;
|
package org.sleuthkit.autopsy.contentviewers;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
@ -25,8 +30,9 @@ import javafx.concurrent.Worker;
|
|||||||
import javafx.scene.web.WebView;
|
import javafx.scene.web.WebView;
|
||||||
import javafx.embed.swing.JFXPanel;
|
import javafx.embed.swing.JFXPanel;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import org.jsoup.Jsoup;
|
import net.htmlparser.jericho.Attribute;
|
||||||
import org.jsoup.nodes.Node;
|
import net.htmlparser.jericho.OutputDocument;
|
||||||
|
import net.htmlparser.jericho.Source;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
@ -38,6 +44,7 @@ import org.w3c.dom.events.EventTarget;
|
|||||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
final class HtmlPanel extends javax.swing.JPanel {
|
final class HtmlPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(HtmlPanel.class.getName());
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final String TEXT_TYPE = "text/plain";
|
private static final String TEXT_TYPE = "text/plain";
|
||||||
private final JFXPanel jfxPanel = new JFXPanel();
|
private final JFXPanel jfxPanel = new JFXPanel();
|
||||||
@ -92,26 +99,76 @@ final class HtmlPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans out input HTML string
|
* Cleans out input HTML string so it will not access resources over the internet
|
||||||
*
|
*
|
||||||
* @param htmlInString The HTML string to cleanse
|
* @param htmlInString The HTML string to cleanse
|
||||||
*
|
*
|
||||||
* @return The cleansed HTML String
|
* @return The cleansed HTML String
|
||||||
*/
|
*/
|
||||||
private String cleanseHTML(String htmlInString) {
|
private String cleanseHTML(String htmlInString) {
|
||||||
org.jsoup.nodes.Document doc = Jsoup.parse(htmlInString);
|
String returnString = "";
|
||||||
// remove all 'img' tags.
|
try {
|
||||||
doc.select("img").stream().forEach(Node::remove);
|
Source source = new Source(new StringReader(htmlInString));
|
||||||
// remove all 'span' tags, these are often images which are ads
|
OutputDocument document = new OutputDocument(source);
|
||||||
doc.select("span").stream().forEach(Node::remove);
|
//remove background images
|
||||||
return doc.html();
|
source.getAllTags().stream().filter((tag) -> (tag.toString().contains("background-image"))).forEachOrdered((tag) -> {
|
||||||
|
document.remove(tag);
|
||||||
|
});
|
||||||
|
//remove images
|
||||||
|
source.getAllElements("img").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove frames
|
||||||
|
source.getAllElements("frame").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove iframes
|
||||||
|
source.getAllElements("iframe").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove pictures
|
||||||
|
source.getAllElements("picture").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove svg
|
||||||
|
source.getAllElements("svg").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove audio
|
||||||
|
source.getAllElements("audio").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove video
|
||||||
|
source.getAllElements("video").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove tracks
|
||||||
|
source.getAllElements("track").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove embeded external elements
|
||||||
|
source.getAllElements("embed").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove linked elements
|
||||||
|
source.getAllElements("link").forEach((element) -> {
|
||||||
|
document.remove(element.getAllTags());
|
||||||
|
});
|
||||||
|
//remove other URI elements such as input boxes
|
||||||
|
List<Attribute> attributesToRemove = source.getURIAttributes();
|
||||||
|
document.remove(attributesToRemove);
|
||||||
|
returnString = document.toString();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to read html for cleaning out URI elements with Jericho", ex);
|
||||||
|
}
|
||||||
|
return returnString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh the panel to reflect the current show/hide images setting.
|
* Refresh the panel to reflect the current show/hide images setting.
|
||||||
*/
|
*/
|
||||||
@Messages({
|
@Messages({
|
||||||
"HtmlPanel_showImagesToggleButton_show=Show Images",
|
"HtmlPanel_showImagesToggleButton_show=Download Images",
|
||||||
"HtmlPanel_showImagesToggleButton_hide=Hide Images",
|
"HtmlPanel_showImagesToggleButton_hide=Hide Images",
|
||||||
"Html_text_display_error=The HTML text cannot be displayed, it may not be correctly formed HTML.",})
|
"Html_text_display_error=The HTML text cannot be displayed, it may not be correctly formed HTML.",})
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
@ -164,7 +221,7 @@ final class HtmlPanel extends javax.swing.JPanel {
|
|||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(showImagesToggleButton)
|
.addComponent(showImagesToggleButton)
|
||||||
.addGap(0, 95, Short.MAX_VALUE))
|
.addGap(0, 75, Short.MAX_VALUE))
|
||||||
.addComponent(htmlJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(htmlJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
|
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.texttranslation.translators;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.squareup.okhttp.MediaType;
|
||||||
|
import com.squareup.okhttp.OkHttpClient;
|
||||||
|
import com.squareup.okhttp.Request;
|
||||||
|
import com.squareup.okhttp.RequestBody;
|
||||||
|
import com.squareup.okhttp.Response;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.TextTranslator;
|
||||||
|
import org.sleuthkit.autopsy.texttranslation.TranslationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates text by making HTTP requests to Bing Translator. This requires a
|
||||||
|
* valid subscription key for a Microsoft Azure account.
|
||||||
|
*/
|
||||||
|
@ServiceProvider(service = TextTranslator.class)
|
||||||
|
public class BingTranslator implements TextTranslator {
|
||||||
|
|
||||||
|
//The target language follows the to= in the string below. You can include multiple target
|
||||||
|
//languages separated by commas. A full list of supported languages is here:
|
||||||
|
//https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support
|
||||||
|
private static final String BASE_URL = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=";
|
||||||
|
private static final int MAX_STRING_LENGTH = 5000;
|
||||||
|
private final BingTranslatorSettingsPanel settingsPanel;
|
||||||
|
private final BingTranslatorSettings settings = new BingTranslatorSettings();
|
||||||
|
// This sends messages to Microsoft.
|
||||||
|
private final OkHttpClient CLIENT = new OkHttpClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Bing Translator
|
||||||
|
*/
|
||||||
|
public BingTranslator() {
|
||||||
|
settingsPanel = new BingTranslatorSettingsPanel(settings.getAuthenticationKey(), settings.getTargetLanguageCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tranlationurl for the specified language code
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param languageCode language code for language to translate to
|
||||||
|
*
|
||||||
|
* @return a string representation of the url to request translation from
|
||||||
|
*/
|
||||||
|
static String getTranlatorUrl(String languageCode) {
|
||||||
|
return BASE_URL + languageCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an input text to the JSON format required by Bing Translator,
|
||||||
|
* posts it to Microsoft, and returns the JSON text response.
|
||||||
|
*
|
||||||
|
* @param string The input text to be translated.
|
||||||
|
*
|
||||||
|
* @return The translation response as a JSON string
|
||||||
|
*
|
||||||
|
* @throws IOException if the request could not be executed due to
|
||||||
|
* cancellation, a connectivity problem or timeout.
|
||||||
|
*/
|
||||||
|
public String postTranslationRequest(String string) throws IOException {
|
||||||
|
MediaType mediaType = MediaType.parse("application/json");
|
||||||
|
|
||||||
|
JsonArray jsonArray = new JsonArray();
|
||||||
|
JsonObject jsonObject = new JsonObject();
|
||||||
|
jsonObject.addProperty("Text", string);
|
||||||
|
jsonArray.add(jsonObject);
|
||||||
|
String bodyString = jsonArray.toString();
|
||||||
|
|
||||||
|
RequestBody body = RequestBody.create(mediaType,
|
||||||
|
bodyString);
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(getTranlatorUrl(settings.getTargetLanguageCode())).post(body)
|
||||||
|
.addHeader("Ocp-Apim-Subscription-Key", settings.getAuthenticationKey())
|
||||||
|
.addHeader("Content-type", "application/json").build();
|
||||||
|
Response response = CLIENT.newCall(request).execute();
|
||||||
|
return response.body().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String translate(String string) throws TranslationException {
|
||||||
|
if (settings.getAuthenticationKey() == null || settings.getAuthenticationKey().isEmpty()) {
|
||||||
|
throw new TranslationException("Bing Translator has not been configured, authentication key needs to be specified");
|
||||||
|
}
|
||||||
|
String toTranslate = string.trim();
|
||||||
|
//Translates some text into English, without specifying the source langauge.
|
||||||
|
|
||||||
|
// HTML files were producing lots of white space at the end
|
||||||
|
//Google Translate required us to replace (\r\n|\n) with <br />
|
||||||
|
//but Bing Translator doesn not have that requirement.
|
||||||
|
//The free account has a maximum file size. If you have a paid account,
|
||||||
|
//you probably still want to limit file size to prevent accidentally
|
||||||
|
//translating very large documents.
|
||||||
|
if (toTranslate.length() > MAX_STRING_LENGTH) {
|
||||||
|
toTranslate = toTranslate.substring(0, MAX_STRING_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String response = postTranslationRequest(toTranslate);
|
||||||
|
return parseJSONResponse(response);
|
||||||
|
} catch (IOException | TranslationException ex) {
|
||||||
|
throw new TranslationException("Exception while attempting to translate using BingTranslator", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({"BingTranslator.name.text=Bing Translator"})
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return Bundle.BingTranslator_name_text();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getComponent() {
|
||||||
|
return settingsPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveSettings() {
|
||||||
|
settings.setAuthenticationKey(settingsPanel.getAuthenticationKey());
|
||||||
|
settings.setTargetLanguageCode(settingsPanel.getTargetLanguageCode());
|
||||||
|
settings.saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the response to get the translated text
|
||||||
|
*
|
||||||
|
* @param json_text the json which was received as a response to a
|
||||||
|
* translation request
|
||||||
|
*
|
||||||
|
* @return the translated text
|
||||||
|
*
|
||||||
|
* @throws TranslationException
|
||||||
|
*/
|
||||||
|
private String parseJSONResponse(String json_text) throws TranslationException {
|
||||||
|
/*
|
||||||
|
* Here is an example of the text we get from Bing when input is "gato",
|
||||||
|
* the Spanish word for cat: [ { "detectedLanguage": { "language": "es",
|
||||||
|
* "score": 1.0 }, "translations": [ { "text": "cat", "to": "en" } ] } ]
|
||||||
|
*/
|
||||||
|
JsonParser parser = new JsonParser();
|
||||||
|
try {
|
||||||
|
JsonArray responses = parser.parse(json_text).getAsJsonArray();
|
||||||
|
//As far as I know, there's always exactly one item in the array.
|
||||||
|
JsonObject response0 = responses.get(0).getAsJsonObject();
|
||||||
|
JsonArray translations = response0.getAsJsonArray("translations");
|
||||||
|
JsonObject translation0 = translations.get(0).getAsJsonObject();
|
||||||
|
return translation0.get("text").getAsString();
|
||||||
|
} catch (IllegalStateException | ClassCastException | NullPointerException | IndexOutOfBoundsException e) {
|
||||||
|
throw new TranslationException("JSON text does not match Bing Translator scheme: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.texttranslation.translators;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to handle the settings associated with the BingTranslator
|
||||||
|
*/
|
||||||
|
public final class BingTranslatorSettings {
|
||||||
|
|
||||||
|
private static final String AUTHENTICATION_KEY = "Credentials";
|
||||||
|
private static final String BING_TRANSLATE_NAME = "BingTranslate";
|
||||||
|
private static final String DEFAULT_AUTHENTICATION = "";
|
||||||
|
private static final String DEFAULT_TARGET_LANGUAGE = "en";
|
||||||
|
private static final String TARGET_LANGUAGE_CODE_KEY = "TargetLanguageCode";
|
||||||
|
private String authenticationKey;
|
||||||
|
private String targetLanguageCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new BingTranslatorSettings object
|
||||||
|
*/
|
||||||
|
BingTranslatorSettings() {
|
||||||
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Authentication key to be used for the Microsoft translation
|
||||||
|
* service
|
||||||
|
*
|
||||||
|
* @return the Authentication key for the service
|
||||||
|
*/
|
||||||
|
String getAuthenticationKey() {
|
||||||
|
return authenticationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Authentication key to be used for the Microsoft translation
|
||||||
|
* service
|
||||||
|
*
|
||||||
|
* @param authKey the Authentication key for the service
|
||||||
|
*/
|
||||||
|
void setAuthenticationKey(String authKey) {
|
||||||
|
authenticationKey = authKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the settings into memory from their on disk storage
|
||||||
|
*/
|
||||||
|
void loadSettings() {
|
||||||
|
if (!ModuleSettings.configExists(BING_TRANSLATE_NAME)) {
|
||||||
|
ModuleSettings.makeConfigFile(BING_TRANSLATE_NAME);
|
||||||
|
}
|
||||||
|
if (ModuleSettings.settingExists(BING_TRANSLATE_NAME, AUTHENTICATION_KEY)) {
|
||||||
|
authenticationKey = ModuleSettings.getConfigSetting(BING_TRANSLATE_NAME, AUTHENTICATION_KEY);
|
||||||
|
}
|
||||||
|
if (authenticationKey == null || StringUtils.isBlank(authenticationKey)) {
|
||||||
|
authenticationKey = DEFAULT_AUTHENTICATION;
|
||||||
|
}
|
||||||
|
if (ModuleSettings.settingExists(BING_TRANSLATE_NAME, TARGET_LANGUAGE_CODE_KEY)) {
|
||||||
|
targetLanguageCode = ModuleSettings.getConfigSetting(BING_TRANSLATE_NAME, TARGET_LANGUAGE_CODE_KEY);
|
||||||
|
}
|
||||||
|
if (targetLanguageCode == null || StringUtils.isBlank(targetLanguageCode)) {
|
||||||
|
targetLanguageCode = DEFAULT_TARGET_LANGUAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the target language code
|
||||||
|
*
|
||||||
|
* @return the code used to identify the target language
|
||||||
|
*/
|
||||||
|
String getTargetLanguageCode() {
|
||||||
|
return targetLanguageCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the target language code. If a blank code is specified it sets the
|
||||||
|
* default code instead.
|
||||||
|
*
|
||||||
|
* @param code the target language code to set
|
||||||
|
*/
|
||||||
|
void setTargetLanguageCode(String code) {
|
||||||
|
if (StringUtils.isBlank(code)) {
|
||||||
|
targetLanguageCode = DEFAULT_TARGET_LANGUAGE;
|
||||||
|
} else {
|
||||||
|
targetLanguageCode = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the setting from memory to their location on disk
|
||||||
|
*/
|
||||||
|
void saveSettings() {
|
||||||
|
ModuleSettings.setConfigSetting(BING_TRANSLATE_NAME, AUTHENTICATION_KEY, authenticationKey);
|
||||||
|
ModuleSettings.setConfigSetting(BING_TRANSLATE_NAME, TARGET_LANGUAGE_CODE_KEY, targetLanguageCode);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,172 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
|
<Component id="warningLabel" min="-2" pref="551" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="targetLanguageLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||||
|
<Component id="targetLanguageComboBox" min="-2" pref="192" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="authenticationKeyLabel" min="-2" pref="100" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="authenticationKeyField" min="-2" pref="486" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="20" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="testButton" min="-2" pref="79" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
|
||||||
|
<Component id="untranslatedLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="testUntranslatedTextField" min="-2" pref="140" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="resultLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="testResultValueLabel" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="authenticationKeyField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="authenticationKeyLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="targetLanguageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="targetLanguageComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="testButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="testUntranslatedTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="untranslatedLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="resultLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="testResultValueLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="warningLabel" min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTextField" name="authenticationKeyField">
|
||||||
|
<Properties>
|
||||||
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="BingTranslatorSettingsPanel.authenticationKeyField.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="warningLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||||
|
<Color blue="0" green="0" red="ff" type="rgb"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="GoogleTranslatorSettingsPanel.warningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="testButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="BingTranslatorSettingsPanel.testButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="testButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="targetLanguageLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="BingTranslatorSettingsPanel.targetLanguageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JComboBox" name="targetLanguageComboBox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||||
|
<StringArray count="0"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="targetLanguageComboBoxSelected"/>
|
||||||
|
</Events>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<LanguageWrapper>"/>
|
||||||
|
</AuxValues>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextField" name="testUntranslatedTextField">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
|
<Connection code="DEFUALT_TEST_STRING" type="code"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="untranslatedLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="BingTranslatorSettingsPanel.untranslatedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="resultLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="BingTranslatorSettingsPanel.resultLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="testResultValueLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="BingTranslatorSettingsPanel.testResultValueLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="authenticationKeyLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="BingTranslatorSettingsPanel.authenticationKeyLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.texttranslation.translators;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.squareup.okhttp.MediaType;
|
||||||
|
import com.squareup.okhttp.OkHttpClient;
|
||||||
|
import com.squareup.okhttp.Request;
|
||||||
|
import com.squareup.okhttp.RequestBody;
|
||||||
|
import com.squareup.okhttp.Response;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings panel for the BingTranslator
|
||||||
|
*/
|
||||||
|
public class BingTranslatorSettingsPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(BingTranslatorSettingsPanel.class.getName());
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final String GET_TARGET_LANGUAGES_URL = "https://api.cognitive.microsofttranslator.com/languages?api-version=3.0&scope=translation";
|
||||||
|
private static final String DEFUALT_TEST_STRING = "traducción exitoso"; //spanish which should translate to something along the lines of "successful translation"
|
||||||
|
private String targetLanguageCode = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form BingTranslatorSettingsPanel
|
||||||
|
*/
|
||||||
|
public BingTranslatorSettingsPanel(String authenticationKey, String code) {
|
||||||
|
initComponents();
|
||||||
|
authenticationKeyField.setText(authenticationKey);
|
||||||
|
authenticationKeyField.getDocument().addDocumentListener(new DocumentListener() {
|
||||||
|
@Override
|
||||||
|
public void insertUpdate(DocumentEvent e) {
|
||||||
|
firePropertyChange("SettingChanged", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeUpdate(DocumentEvent e) {
|
||||||
|
firePropertyChange("SettingChanged", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
firePropertyChange("SettingChanged", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
populateComboBox();
|
||||||
|
selectLanguageByCode(code);
|
||||||
|
targetLanguageCode = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the target language combo box with available target languages
|
||||||
|
*/
|
||||||
|
@Messages({"BingTranslatorSettingsPanel.warning.targetLanguageFailure=Unable to get list of target languages or parse the result that was received"})
|
||||||
|
private void populateComboBox() {
|
||||||
|
Request get_request = new Request.Builder()
|
||||||
|
.url(GET_TARGET_LANGUAGES_URL).build();
|
||||||
|
try {
|
||||||
|
Response response = new OkHttpClient().newCall(get_request).execute();
|
||||||
|
JsonParser parser = new JsonParser();
|
||||||
|
String responseBody = response.body().string();
|
||||||
|
JsonElement elementBody = parser.parse(responseBody);
|
||||||
|
JsonObject asObject = elementBody.getAsJsonObject();
|
||||||
|
JsonElement translationElement = asObject.get("translation");
|
||||||
|
JsonObject responses = translationElement.getAsJsonObject();
|
||||||
|
responses.entrySet().forEach((entry) -> {
|
||||||
|
targetLanguageComboBox.addItem(new LanguageWrapper(entry.getKey(), entry.getValue().getAsJsonObject().get("name").getAsString()));
|
||||||
|
});
|
||||||
|
targetLanguageComboBox.setEnabled(true);
|
||||||
|
} catch (IOException | IllegalStateException | ClassCastException | NullPointerException | IndexOutOfBoundsException ex) {
|
||||||
|
logger.log(Level.SEVERE, Bundle.BingTranslatorSettingsPanel_warning_targetLanguageFailure(), ex);
|
||||||
|
warningLabel.setText(Bundle.BingTranslatorSettingsPanel_warning_targetLanguageFailure());
|
||||||
|
targetLanguageComboBox.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a language code select the corresponding language in the combo box
|
||||||
|
* if it is present
|
||||||
|
*
|
||||||
|
* @param code language code such as "en" for English
|
||||||
|
*/
|
||||||
|
private void selectLanguageByCode(String code) {
|
||||||
|
for (int i = 0; i < targetLanguageComboBox.getModel().getSize(); i++) {
|
||||||
|
if (targetLanguageComboBox.getModel().getElementAt(i).getLanguageCode().equals(code)) {
|
||||||
|
targetLanguageComboBox.setSelectedIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
authenticationKeyField = new javax.swing.JTextField();
|
||||||
|
warningLabel = new javax.swing.JLabel();
|
||||||
|
testButton = new javax.swing.JButton();
|
||||||
|
targetLanguageLabel = new javax.swing.JLabel();
|
||||||
|
targetLanguageComboBox = new javax.swing.JComboBox<>();
|
||||||
|
testUntranslatedTextField = new javax.swing.JTextField();
|
||||||
|
untranslatedLabel = new javax.swing.JLabel();
|
||||||
|
resultLabel = new javax.swing.JLabel();
|
||||||
|
testResultValueLabel = new javax.swing.JLabel();
|
||||||
|
authenticationKeyLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
|
authenticationKeyField.setToolTipText(org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.authenticationKeyField.toolTipText")); // NOI18N
|
||||||
|
|
||||||
|
warningLabel.setForeground(new java.awt.Color(255, 0, 0));
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.warningLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(testButton, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.testButton.text")); // NOI18N
|
||||||
|
testButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
testButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(targetLanguageLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.targetLanguageLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
targetLanguageComboBox.setEnabled(false);
|
||||||
|
targetLanguageComboBox.addItemListener(new java.awt.event.ItemListener() {
|
||||||
|
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||||
|
targetLanguageComboBoxSelected(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
testUntranslatedTextField.setText(DEFUALT_TEST_STRING);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(untranslatedLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.untranslatedLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(resultLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.resultLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(testResultValueLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.testResultValueLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(authenticationKeyLabel, org.openide.util.NbBundle.getMessage(BingTranslatorSettingsPanel.class, "BingTranslatorSettingsPanel.authenticationKeyLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
|
.addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 551, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(targetLanguageLabel)
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 192, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(authenticationKeyLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(authenticationKeyField, javax.swing.GroupLayout.PREFERRED_SIZE, 486, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGap(0, 20, Short.MAX_VALUE))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(testButton, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGap(25, 25, 25)
|
||||||
|
.addComponent(untranslatedLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(resultLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(testResultValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||||
|
.addContainerGap())))
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(authenticationKeyField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(authenticationKeyLabel))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(targetLanguageLabel)
|
||||||
|
.addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(testButton)
|
||||||
|
.addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(untranslatedLabel)
|
||||||
|
.addComponent(resultLabel)
|
||||||
|
.addComponent(testResultValueLabel))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addContainerGap())
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@Messages({"BingTranslatorSettingsPanel.warning.invalidKey=Invalid translation authentication key"})
|
||||||
|
private void testButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_testButtonActionPerformed
|
||||||
|
if (testTranslationSetup()) {
|
||||||
|
warningLabel.setText("");
|
||||||
|
} else {
|
||||||
|
warningLabel.setText(Bundle.BingTranslatorSettingsPanel_warning_invalidKey());
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_testButtonActionPerformed
|
||||||
|
|
||||||
|
private void targetLanguageComboBoxSelected(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_targetLanguageComboBoxSelected
|
||||||
|
String selectedCode = ((LanguageWrapper) targetLanguageComboBox.getSelectedItem()).getLanguageCode();
|
||||||
|
if (!StringUtils.isBlank(selectedCode) && !selectedCode.equals(targetLanguageCode)) {
|
||||||
|
targetLanguageCode = selectedCode;
|
||||||
|
firePropertyChange("SettingChanged", true, false);
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_targetLanguageComboBoxSelected
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JTextField authenticationKeyField;
|
||||||
|
private javax.swing.JLabel authenticationKeyLabel;
|
||||||
|
private javax.swing.JLabel resultLabel;
|
||||||
|
private javax.swing.JComboBox<LanguageWrapper> targetLanguageComboBox;
|
||||||
|
private javax.swing.JLabel targetLanguageLabel;
|
||||||
|
private javax.swing.JButton testButton;
|
||||||
|
private javax.swing.JLabel testResultValueLabel;
|
||||||
|
private javax.swing.JTextField testUntranslatedTextField;
|
||||||
|
private javax.swing.JLabel untranslatedLabel;
|
||||||
|
private javax.swing.JLabel warningLabel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to translate the text specified in the Untranslated field using
|
||||||
|
* the settings currently specified but not necessarily saved
|
||||||
|
*
|
||||||
|
* @return true if the translation was able to be performed, false otherwise
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private boolean testTranslationSetup() {
|
||||||
|
testResultValueLabel.setText("");
|
||||||
|
MediaType mediaType = MediaType.parse("application/json");
|
||||||
|
JsonArray jsonArray = new JsonArray();
|
||||||
|
JsonObject jsonObject = new JsonObject();
|
||||||
|
jsonObject.addProperty("Text", testUntranslatedTextField.getText());
|
||||||
|
jsonArray.add(jsonObject);
|
||||||
|
String bodyString = jsonArray.toString();
|
||||||
|
|
||||||
|
RequestBody body = RequestBody.create(mediaType,
|
||||||
|
bodyString);
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(BingTranslator.getTranlatorUrl(targetLanguageCode)).post(body)
|
||||||
|
.addHeader("Ocp-Apim-Subscription-Key", authenticationKeyField.getText())
|
||||||
|
.addHeader("Content-type", "application/json").build();
|
||||||
|
try {
|
||||||
|
Response response = new OkHttpClient().newCall(request).execute();
|
||||||
|
JsonParser parser = new JsonParser();
|
||||||
|
JsonArray responses = parser.parse(response.body().string()).getAsJsonArray();
|
||||||
|
//As far as I know, there's always exactly one item in the array.
|
||||||
|
JsonObject response0 = responses.get(0).getAsJsonObject();
|
||||||
|
JsonArray translations = response0.getAsJsonArray("translations");
|
||||||
|
JsonObject translation0 = translations.get(0).getAsJsonObject();
|
||||||
|
testResultValueLabel.setText(translation0.get("text").getAsString());
|
||||||
|
return true;
|
||||||
|
} catch (IOException | IllegalStateException | ClassCastException | NullPointerException | IndexOutOfBoundsException e) {
|
||||||
|
logger.log(Level.WARNING, "Test of Bing Translator failed due to exception", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently set authentication key to be used for the Microsoft
|
||||||
|
* translation service
|
||||||
|
*
|
||||||
|
* @return the authentication key specified in the textarea
|
||||||
|
*/
|
||||||
|
String getAuthenticationKey() {
|
||||||
|
return authenticationKeyField.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently selected target language code
|
||||||
|
*
|
||||||
|
* @return the target language code of the language selected in the combobox
|
||||||
|
*/
|
||||||
|
String getTargetLanguageCode() {
|
||||||
|
return targetLanguageCode;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,15 @@
|
|||||||
GoogleTranslatorSettingsPanel.browseButton.text=Browse
|
GoogleTranslatorSettingsPanel.browseButton.text=Browse
|
||||||
GoogleTranslatorSettingsPanel.credentialsLabel.text=Credentials:
|
GoogleTranslatorSettingsPanel.credentialsLabel.text=Credentials Path:
|
||||||
GoogleTranslatorSettingsPanel.warningLabel.text=
|
GoogleTranslatorSettingsPanel.warningLabel.text=
|
||||||
GoogleTranslatorSettingsPanel.targetLanguageLabel.text=Target Language:
|
GoogleTranslatorSettingsPanel.targetLanguageLabel.text=Target Language:
|
||||||
|
BingTranslatorSettingsPanel.testButton.text=Test
|
||||||
|
BingTranslatorSettingsPanel.testResultValueLabel.text=
|
||||||
|
BingTranslatorSettingsPanel.resultLabel.text=Result:
|
||||||
|
BingTranslatorSettingsPanel.untranslatedLabel.text=Untranslated:
|
||||||
|
BingTranslatorSettingsPanel.targetLanguageLabel.text=Target Language:
|
||||||
|
BingTranslatorSettingsPanel.authenticationKeyField.toolTipText=Enter the hash for the
|
||||||
|
GoogleTranslatorSettingsPanel.testButton.text=Test
|
||||||
|
GoogleTranslatorSettingsPanel.untranslatedLabel.text=Untranslated:
|
||||||
|
GoogleTranslatorSettingsPanel.resultLabel.text=Result:
|
||||||
|
GoogleTranslatorSettingsPanel.testResultValueLabel.text=
|
||||||
|
BingTranslatorSettingsPanel.authenticationKeyLabel.text=Authentication Key:
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
|
BingTranslator.name.text=Bing Translator
|
||||||
|
BingTranslatorSettingsPanel.warning.invalidKey=Invalid translation authentication key
|
||||||
|
BingTranslatorSettingsPanel.warning.targetLanguageFailure=Unable to get list of target languages or parse the result that was received
|
||||||
GoogleTranslator.name.text=Google Translate
|
GoogleTranslator.name.text=Google Translate
|
||||||
GoogleTranslatorSettingsPanel.browseButton.text=Browse
|
GoogleTranslatorSettingsPanel.browseButton.text=Browse
|
||||||
GoogleTranslatorSettingsPanel.credentialsLabel.text=Credentials:
|
GoogleTranslatorSettingsPanel.credentialsLabel.text=Credentials Path:
|
||||||
GoogleTranslatorSettingsPanel.errorMessage.fileNotFound=Credentials file not found, please set the location to be a valid JSON credentials file.
|
GoogleTranslatorSettingsPanel.errorMessage.fileNotFound=Credentials file not found, please set the location to be a valid JSON credentials file.
|
||||||
GoogleTranslatorSettingsPanel.errorMessage.noFileSelected=A JSON file must be selected to provide your credentials for Google Translate.
|
GoogleTranslatorSettingsPanel.errorMessage.noFileSelected=A JSON file must be selected to provide your credentials for Google Translate.
|
||||||
|
GoogleTranslatorSettingsPanel.errorMessage.translationFailure=Translation failure with specified credentials
|
||||||
GoogleTranslatorSettingsPanel.errorMessage.unableToMakeCredentials=Unable to construct credentials object from credentials file, please set the location to be a valid JSON credentials file.
|
GoogleTranslatorSettingsPanel.errorMessage.unableToMakeCredentials=Unable to construct credentials object from credentials file, please set the location to be a valid JSON credentials file.
|
||||||
GoogleTranslatorSettingsPanel.errorMessage.unableToReadCredentials=Unable to read credentials from credentials file, please set the location to be a valid JSON credentials file.
|
GoogleTranslatorSettingsPanel.errorMessage.unableToReadCredentials=Unable to read credentials from credentials file, please set the location to be a valid JSON credentials file.
|
||||||
GoogleTranslatorSettingsPanel.errorMessage.unknownFailureGetting=Failure getting list of supported languages with current credentials file.
|
GoogleTranslatorSettingsPanel.errorMessage.unknownFailureGetting=Failure getting list of supported languages with current credentials file.
|
||||||
@ -11,3 +15,14 @@ GoogleTranslatorSettingsPanel.fileChooser.confirmButton=Select
|
|||||||
GoogleTranslatorSettingsPanel.json.description=JSON Files
|
GoogleTranslatorSettingsPanel.json.description=JSON Files
|
||||||
GoogleTranslatorSettingsPanel.warningLabel.text=
|
GoogleTranslatorSettingsPanel.warningLabel.text=
|
||||||
GoogleTranslatorSettingsPanel.targetLanguageLabel.text=Target Language:
|
GoogleTranslatorSettingsPanel.targetLanguageLabel.text=Target Language:
|
||||||
|
BingTranslatorSettingsPanel.testButton.text=Test
|
||||||
|
BingTranslatorSettingsPanel.testResultValueLabel.text=
|
||||||
|
BingTranslatorSettingsPanel.resultLabel.text=Result:
|
||||||
|
BingTranslatorSettingsPanel.untranslatedLabel.text=Untranslated:
|
||||||
|
BingTranslatorSettingsPanel.targetLanguageLabel.text=Target Language:
|
||||||
|
BingTranslatorSettingsPanel.authenticationKeyField.toolTipText=Enter the hash for the
|
||||||
|
GoogleTranslatorSettingsPanel.testButton.text=Test
|
||||||
|
GoogleTranslatorSettingsPanel.untranslatedLabel.text=Untranslated:
|
||||||
|
GoogleTranslatorSettingsPanel.resultLabel.text=Result:
|
||||||
|
GoogleTranslatorSettingsPanel.testResultValueLabel.text=
|
||||||
|
BingTranslatorSettingsPanel.authenticationKeyLabel.text=Authentication Key:
|
||||||
|
@ -32,8 +32,10 @@ import java.net.InetAddress;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||||
import org.sleuthkit.autopsy.texttranslation.TextTranslator;
|
import org.sleuthkit.autopsy.texttranslation.TextTranslator;
|
||||||
import org.sleuthkit.autopsy.texttranslation.TranslationException;
|
import org.sleuthkit.autopsy.texttranslation.TranslationException;
|
||||||
|
|
||||||
@ -59,15 +61,22 @@ public final class GoogleTranslator implements TextTranslator {
|
|||||||
loadTranslator();
|
loadTranslator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if google is able to be reached
|
||||||
|
*
|
||||||
|
* @return true if it can be, false otherwise
|
||||||
|
*/
|
||||||
private static boolean googleIsReachable() {
|
private static boolean googleIsReachable() {
|
||||||
String host = "www.google.com";
|
String host = "www.google.com";
|
||||||
InetAddress address;
|
InetAddress address;
|
||||||
try {
|
try {
|
||||||
address = InetAddress.getByName(host);
|
address = InetAddress.getByName(host);
|
||||||
return address.isReachable(1500);
|
return address.isReachable(1500);
|
||||||
}catch (UnknownHostException ex) {
|
} catch (UnknownHostException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to reach google.com due to unknown host", ex);
|
||||||
return false;
|
return false;
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to reach google.com due IOException", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,6 +112,10 @@ public final class GoogleTranslator implements TextTranslator {
|
|||||||
|
|
||||||
// put back the newlines
|
// put back the newlines
|
||||||
translatedString = translatedString.replaceAll("<br />", "\n");
|
translatedString = translatedString.replaceAll("<br />", "\n");
|
||||||
|
|
||||||
|
// With our current settings, Google Translate outputs HTML
|
||||||
|
// so we need to undo the escape characters.
|
||||||
|
translatedString = EscapeUtil.unEscapeHtml(translatedString);
|
||||||
return translatedString;
|
return translatedString;
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
//Catching throwables because some of this Google Translate code throws throwables
|
//Catching throwables because some of this Google Translate code throws throwables
|
||||||
@ -125,16 +138,20 @@ public final class GoogleTranslator implements TextTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the Google Cloud Translation service give the currently saved
|
* Load the Google Cloud Translation service given the currently saved
|
||||||
* settings
|
* settings
|
||||||
*/
|
*/
|
||||||
private void loadTranslator() {
|
private void loadTranslator() {
|
||||||
InputStream credentialStream = null;
|
InputStream credentialStream = null;
|
||||||
Credentials creds = null;
|
Credentials creds = null;
|
||||||
try {
|
if (StringUtils.isBlank(settings.getCredentialPath())) {
|
||||||
credentialStream = new FileInputStream(settings.getCredentialPath());
|
logger.log(Level.INFO, "No credentials file has been provided for Google Translator");
|
||||||
} catch (FileNotFoundException ex) {
|
} else {
|
||||||
logger.log(Level.WARNING, "JSON file for GoogleTranslator credentials not found", ex);
|
try {
|
||||||
|
credentialStream = new FileInputStream(settings.getCredentialPath());
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
logger.log(Level.WARNING, "JSON file for GoogleTranslator credentials not found", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (credentialStream != null) {
|
if (credentialStream != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -92,12 +92,14 @@ public final class GoogleTranslatorSettings {
|
|||||||
}
|
}
|
||||||
if (ModuleSettings.settingExists(GOOGLE_TRANSLATE_NAME, TARGET_LANGUAGE_CODE_KEY)) {
|
if (ModuleSettings.settingExists(GOOGLE_TRANSLATE_NAME, TARGET_LANGUAGE_CODE_KEY)) {
|
||||||
targetLanguageCode = ModuleSettings.getConfigSetting(GOOGLE_TRANSLATE_NAME, TARGET_LANGUAGE_CODE_KEY);
|
targetLanguageCode = ModuleSettings.getConfigSetting(GOOGLE_TRANSLATE_NAME, TARGET_LANGUAGE_CODE_KEY);
|
||||||
} else {
|
}
|
||||||
|
if (targetLanguageCode == null || StringUtils.isBlank(targetLanguageCode)) {
|
||||||
targetLanguageCode = DEFAULT_TARGET_LANGUAGE;
|
targetLanguageCode = DEFAULT_TARGET_LANGUAGE;
|
||||||
}
|
}
|
||||||
if (ModuleSettings.settingExists(GOOGLE_TRANSLATE_NAME, CREDENTIAL_PATH_KEY)) {
|
if (ModuleSettings.settingExists(GOOGLE_TRANSLATE_NAME, CREDENTIAL_PATH_KEY)) {
|
||||||
credentialPath = ModuleSettings.getConfigSetting(GOOGLE_TRANSLATE_NAME, CREDENTIAL_PATH_KEY);
|
credentialPath = ModuleSettings.getConfigSetting(GOOGLE_TRANSLATE_NAME, CREDENTIAL_PATH_KEY);
|
||||||
} else {
|
}
|
||||||
|
if (credentialPath == null) {
|
||||||
credentialPath = DEFAULT_CREDENTIAL_PATH;
|
credentialPath = DEFAULT_CREDENTIAL_PATH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,9 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
|
||||||
<Component id="warningLabel" min="-2" pref="551" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||||
<Component id="credentialsLabel" max="32767" attributes="0"/>
|
<Component id="credentialsLabel" max="32767" attributes="0"/>
|
||||||
@ -31,7 +27,7 @@
|
|||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" attributes="0">
|
<Group type="102" attributes="0">
|
||||||
<Component id="credentialsPathField" pref="443" max="32767" attributes="0"/>
|
<Component id="credentialsPathField" pref="451" max="32767" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="browseButton" min="-2" max="-2" attributes="0"/>
|
<Component id="browseButton" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
|
||||||
@ -42,6 +38,18 @@
|
|||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
<Component id="warningLabel" min="-2" pref="551" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="testButton" min="-2" pref="83" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
|
<Component id="untranslatedLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="testUntranslatedTextField" min="-2" pref="140" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="resultLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="testResultValueLabel" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
@ -60,9 +68,16 @@
|
|||||||
<Component id="targetLanguageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="targetLanguageLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="targetLanguageComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="targetLanguageComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace pref="15" max="32767" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="testButton" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="testUntranslatedTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="untranslatedLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="resultLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="testResultValueLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="warningLabel" min="-2" pref="18" max="-2" attributes="0"/>
|
<Component id="warningLabel" min="-2" pref="18" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="23" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -98,7 +113,7 @@
|
|||||||
<Property name="enabled" type="boolean" value="false"/>
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.texttranslation.translators.GoogleLanguageWrapper>"/>
|
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.texttranslation.translators.LanguageWrapper>"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
</Component>
|
</Component>
|
||||||
<Component class="javax.swing.JLabel" name="targetLanguageLabel">
|
<Component class="javax.swing.JLabel" name="targetLanguageLabel">
|
||||||
@ -118,5 +133,47 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="testResultValueLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="GoogleTranslatorSettingsPanel.testResultValueLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="resultLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="GoogleTranslatorSettingsPanel.resultLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="untranslatedLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="GoogleTranslatorSettingsPanel.untranslatedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextField" name="testUntranslatedTextField">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||||
|
<Connection code="DEFUALT_TEST_STRING" type="code"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="testButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/texttranslation/translators/Bundle.properties" key="GoogleTranslatorSettingsPanel.testButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="enabled" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="testButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -21,7 +21,9 @@ package org.sleuthkit.autopsy.texttranslation.translators;
|
|||||||
import com.google.auth.Credentials;
|
import com.google.auth.Credentials;
|
||||||
import com.google.auth.oauth2.ServiceAccountCredentials;
|
import com.google.auth.oauth2.ServiceAccountCredentials;
|
||||||
import com.google.cloud.translate.Language;
|
import com.google.cloud.translate.Language;
|
||||||
|
import com.google.cloud.translate.Translate;
|
||||||
import com.google.cloud.translate.TranslateOptions;
|
import com.google.cloud.translate.TranslateOptions;
|
||||||
|
import com.google.cloud.translate.Translation;
|
||||||
import java.awt.event.ItemListener;
|
import java.awt.event.ItemListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -44,6 +46,7 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(GoogleTranslatorSettingsPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(GoogleTranslatorSettingsPanel.class.getName());
|
||||||
private static final String JSON_EXTENSION = "json";
|
private static final String JSON_EXTENSION = "json";
|
||||||
|
private static final String DEFUALT_TEST_STRING = "traducción exitoso"; //spanish which should translate to something along the lines of "successful translation"
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final ItemListener listener = new ComboBoxSelectionListener();
|
private final ItemListener listener = new ComboBoxSelectionListener();
|
||||||
private String targetLanguageCode = "";
|
private String targetLanguageCode = "";
|
||||||
@ -60,16 +63,15 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Private method to make a temporary translation service given the current
|
* Private method to make a temporary translation service given the current
|
||||||
* settings and use it to retrieve the available target languages for
|
* settings with unsaved settings.
|
||||||
* population of combobox with target language with unsaved settings.
|
|
||||||
*
|
*
|
||||||
* @return A list of Languages
|
* @return A Translate object which is the translation service
|
||||||
*/
|
*/
|
||||||
@Messages({"GoogleTranslatorSettingsPanel.errorMessage.fileNotFound=Credentials file not found, please set the location to be a valid JSON credentials file.",
|
@Messages({"GoogleTranslatorSettingsPanel.errorMessage.fileNotFound=Credentials file not found, please set the location to be a valid JSON credentials file.",
|
||||||
"GoogleTranslatorSettingsPanel.errorMessage.unableToReadCredentials=Unable to read credentials from credentials file, please set the location to be a valid JSON credentials file.",
|
"GoogleTranslatorSettingsPanel.errorMessage.unableToReadCredentials=Unable to read credentials from credentials file, please set the location to be a valid JSON credentials file.",
|
||||||
"GoogleTranslatorSettingsPanel.errorMessage.unableToMakeCredentials=Unable to construct credentials object from credentials file, please set the location to be a valid JSON credentials file.",
|
"GoogleTranslatorSettingsPanel.errorMessage.unableToMakeCredentials=Unable to construct credentials object from credentials file, please set the location to be a valid JSON credentials file.",
|
||||||
"GoogleTranslatorSettingsPanel.errorMessage.unknownFailureGetting=Failure getting list of supported languages with current credentials file.",})
|
"GoogleTranslatorSettingsPanel.errorMessage.unknownFailureGetting=Failure getting list of supported languages with current credentials file.",})
|
||||||
private List<Language> getListOfTargetLanguages() {
|
private Translate getTemporaryTranslationService() {
|
||||||
//This method also has the side effect of more or less validating the JSON file which was selected as it is necessary to get the list of target languages
|
//This method also has the side effect of more or less validating the JSON file which was selected as it is necessary to get the list of target languages
|
||||||
try {
|
try {
|
||||||
InputStream credentialStream;
|
InputStream credentialStream;
|
||||||
@ -77,31 +79,31 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
credentialStream = new FileInputStream(credentialsPathField.getText());
|
credentialStream = new FileInputStream(credentialsPathField.getText());
|
||||||
} catch (FileNotFoundException ignored) {
|
} catch (FileNotFoundException ignored) {
|
||||||
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_fileNotFound());
|
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_fileNotFound());
|
||||||
return new ArrayList<>();
|
return null;
|
||||||
}
|
}
|
||||||
Credentials creds;
|
Credentials creds;
|
||||||
try {
|
try {
|
||||||
creds = ServiceAccountCredentials.fromStream(credentialStream);
|
creds = ServiceAccountCredentials.fromStream(credentialStream);
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unableToMakeCredentials());
|
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unableToMakeCredentials());
|
||||||
return new ArrayList<>();
|
return null;
|
||||||
}
|
}
|
||||||
if (creds == null) {
|
if (creds == null) {
|
||||||
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unableToReadCredentials());
|
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unableToReadCredentials());
|
||||||
logger.log(Level.WARNING, "Credentials were not successfully made, no translations will be available from the GoogleTranslator");
|
logger.log(Level.WARNING, "Credentials were not successfully made, no translations will be available from the GoogleTranslator");
|
||||||
return new ArrayList<>();
|
return null;
|
||||||
} else {
|
} else {
|
||||||
TranslateOptions.Builder builder = TranslateOptions.newBuilder();
|
TranslateOptions.Builder builder = TranslateOptions.newBuilder();
|
||||||
builder.setCredentials(creds);
|
builder.setCredentials(creds);
|
||||||
builder.setTargetLanguage(targetLanguageCode); //localize the list to the currently selected target language
|
builder.setTargetLanguage(targetLanguageCode); //localize the list to the currently selected target language
|
||||||
warningLabel.setText(""); //clear any previous warning text
|
warningLabel.setText(""); //clear any previous warning text
|
||||||
return builder.build().getService().listSupportedLanguages();
|
return builder.build().getService();
|
||||||
}
|
}
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
//Catching throwables because some of this Google Translate code throws throwables
|
//Catching throwables because some of this Google Translate code throws throwables
|
||||||
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unknownFailureGetting());
|
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unknownFailureGetting());
|
||||||
logger.log(Level.WARNING, "Throwable caught while getting list of supported languages", throwable);
|
logger.log(Level.WARNING, "Throwable caught while getting list of supported languages", throwable);
|
||||||
return new ArrayList<>();
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,29 +116,51 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
targetLanguageComboBox.removeItemListener(listener);
|
targetLanguageComboBox.removeItemListener(listener);
|
||||||
try {
|
try {
|
||||||
if (!StringUtils.isBlank(credentialsPathField.getText())) {
|
if (!StringUtils.isBlank(credentialsPathField.getText())) {
|
||||||
List<Language> listSupportedLanguages = getListOfTargetLanguages();
|
List<Language> listSupportedLanguages;
|
||||||
|
Translate tempService = getTemporaryTranslationService();
|
||||||
|
if (tempService != null) {
|
||||||
|
listSupportedLanguages = tempService.listSupportedLanguages();
|
||||||
|
} else {
|
||||||
|
listSupportedLanguages = new ArrayList<>();
|
||||||
|
}
|
||||||
targetLanguageComboBox.removeAllItems();
|
targetLanguageComboBox.removeAllItems();
|
||||||
if (!listSupportedLanguages.isEmpty()) {
|
if (!listSupportedLanguages.isEmpty()) {
|
||||||
listSupportedLanguages.forEach((lang) -> {
|
listSupportedLanguages.forEach((lang) -> {
|
||||||
targetLanguageComboBox.addItem(new GoogleLanguageWrapper(lang));
|
targetLanguageComboBox.addItem(new LanguageWrapper(lang));
|
||||||
});
|
});
|
||||||
selectLanguageByCode(targetLanguageCode);
|
selectLanguageByCode(targetLanguageCode);
|
||||||
targetLanguageComboBox.addItemListener(listener);
|
targetLanguageComboBox.addItemListener(listener);
|
||||||
targetLanguageComboBox.setEnabled(true);
|
enableControls(true);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
targetLanguageComboBox.setEnabled(false);
|
enableControls(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_noFileSelected());
|
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_noFileSelected());
|
||||||
targetLanguageComboBox.setEnabled(false);
|
enableControls(false);
|
||||||
}
|
}
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unknownFailurePopulating());
|
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_unknownFailurePopulating());
|
||||||
logger.log(Level.WARNING, "Throwable caught while populating list of supported languages", throwable);
|
logger.log(Level.WARNING, "Throwable caught while populating list of supported languages", throwable);
|
||||||
targetLanguageComboBox.setEnabled(false);
|
enableControls(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to enable/disable all controls which are dependent on valid
|
||||||
|
* credentials having been provided
|
||||||
|
*
|
||||||
|
* @param enabled true to enable the controls, false to disable them
|
||||||
|
*/
|
||||||
|
private void enableControls(boolean enabled) {
|
||||||
|
targetLanguageComboBox.setEnabled(enabled);
|
||||||
|
testButton.setEnabled(enabled);
|
||||||
|
testResultValueLabel.setEnabled(enabled);
|
||||||
|
testUntranslatedTextField.setEnabled(enabled);
|
||||||
|
untranslatedLabel.setEnabled(enabled);
|
||||||
|
resultLabel.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a language code select the corresponding language in the combo box
|
* Given a language code select the corresponding language in the combo box
|
||||||
* if it is present
|
* if it is present
|
||||||
@ -145,7 +169,7 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
*/
|
*/
|
||||||
private void selectLanguageByCode(String code) {
|
private void selectLanguageByCode(String code) {
|
||||||
for (int i = 0; i < targetLanguageComboBox.getModel().getSize(); i++) {
|
for (int i = 0; i < targetLanguageComboBox.getModel().getSize(); i++) {
|
||||||
if (targetLanguageComboBox.getItemAt(i).getLanguage().getCode().equals(code)) {
|
if (targetLanguageComboBox.getItemAt(i).getLanguageCode().equals(code)) {
|
||||||
targetLanguageComboBox.setSelectedIndex(i);
|
targetLanguageComboBox.setSelectedIndex(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -167,6 +191,11 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
targetLanguageComboBox = new javax.swing.JComboBox<>();
|
targetLanguageComboBox = new javax.swing.JComboBox<>();
|
||||||
targetLanguageLabel = new javax.swing.JLabel();
|
targetLanguageLabel = new javax.swing.JLabel();
|
||||||
warningLabel = new javax.swing.JLabel();
|
warningLabel = new javax.swing.JLabel();
|
||||||
|
testResultValueLabel = new javax.swing.JLabel();
|
||||||
|
resultLabel = new javax.swing.JLabel();
|
||||||
|
untranslatedLabel = new javax.swing.JLabel();
|
||||||
|
testUntranslatedTextField = new javax.swing.JTextField();
|
||||||
|
testButton = new javax.swing.JButton();
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(credentialsLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.credentialsLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(credentialsLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.credentialsLabel.text")); // NOI18N
|
||||||
|
|
||||||
@ -186,6 +215,25 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
warningLabel.setForeground(new java.awt.Color(255, 0, 0));
|
warningLabel.setForeground(new java.awt.Color(255, 0, 0));
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.warningLabel.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.warningLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(testResultValueLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.testResultValueLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(resultLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.resultLabel.text")); // NOI18N
|
||||||
|
resultLabel.setEnabled(false);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(untranslatedLabel, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.untranslatedLabel.text")); // NOI18N
|
||||||
|
untranslatedLabel.setEnabled(false);
|
||||||
|
|
||||||
|
testUntranslatedTextField.setText(DEFUALT_TEST_STRING);
|
||||||
|
testUntranslatedTextField.setEnabled(false);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(testButton, org.openide.util.NbBundle.getMessage(GoogleTranslatorSettingsPanel.class, "GoogleTranslatorSettingsPanel.testButton.text")); // NOI18N
|
||||||
|
testButton.setEnabled(false);
|
||||||
|
testButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
testButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
this.setLayout(layout);
|
this.setLayout(layout);
|
||||||
layout.setHorizontalGroup(
|
layout.setHorizontalGroup(
|
||||||
@ -193,9 +241,6 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
|
||||||
.addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 551, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||||
.addComponent(credentialsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(credentialsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
@ -203,13 +248,24 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(credentialsPathField, javax.swing.GroupLayout.DEFAULT_SIZE, 443, Short.MAX_VALUE)
|
.addComponent(credentialsPathField, javax.swing.GroupLayout.DEFAULT_SIZE, 451, Short.MAX_VALUE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(browseButton)
|
.addComponent(browseButton)
|
||||||
.addGap(14, 14, 14))
|
.addGap(14, 14, 14))
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 317, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 317, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addGap(0, 0, Short.MAX_VALUE))))))
|
.addGap(0, 0, Short.MAX_VALUE))))
|
||||||
|
.addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 551, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(testButton, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(untranslatedLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(resultLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(testResultValueLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
@ -223,9 +279,15 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(targetLanguageLabel)
|
.addComponent(targetLanguageLabel)
|
||||||
.addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
.addComponent(targetLanguageComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 15, Short.MAX_VALUE)
|
||||||
.addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addContainerGap(23, Short.MAX_VALUE))
|
.addComponent(testButton)
|
||||||
|
.addComponent(testUntranslatedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(untranslatedLabel)
|
||||||
|
.addComponent(resultLabel)
|
||||||
|
.addComponent(testResultValueLabel))
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(warningLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
@ -249,12 +311,33 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
}//GEN-LAST:event_browseButtonActionPerformed
|
}//GEN-LAST:event_browseButtonActionPerformed
|
||||||
|
|
||||||
|
@Messages({"GoogleTranslatorSettingsPanel.errorMessage.translationFailure=Translation failure with specified credentials"})
|
||||||
|
private void testButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_testButtonActionPerformed
|
||||||
|
testResultValueLabel.setText("");
|
||||||
|
Translate tempTranslate = getTemporaryTranslationService();
|
||||||
|
if (tempTranslate != null) {
|
||||||
|
try {
|
||||||
|
Translation translation = tempTranslate.translate(testUntranslatedTextField.getText());
|
||||||
|
testResultValueLabel.setText(translation.getTranslatedText());
|
||||||
|
warningLabel.setText("");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
warningLabel.setText(Bundle.GoogleTranslatorSettingsPanel_errorMessage_translationFailure());
|
||||||
|
logger.log(Level.WARNING, Bundle.GoogleTranslatorSettingsPanel_errorMessage_translationFailure(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_testButtonActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton browseButton;
|
private javax.swing.JButton browseButton;
|
||||||
private javax.swing.JLabel credentialsLabel;
|
private javax.swing.JLabel credentialsLabel;
|
||||||
private javax.swing.JTextField credentialsPathField;
|
private javax.swing.JTextField credentialsPathField;
|
||||||
private javax.swing.JComboBox<org.sleuthkit.autopsy.texttranslation.translators.GoogleLanguageWrapper> targetLanguageComboBox;
|
private javax.swing.JLabel resultLabel;
|
||||||
|
private javax.swing.JComboBox<org.sleuthkit.autopsy.texttranslation.translators.LanguageWrapper> targetLanguageComboBox;
|
||||||
private javax.swing.JLabel targetLanguageLabel;
|
private javax.swing.JLabel targetLanguageLabel;
|
||||||
|
private javax.swing.JButton testButton;
|
||||||
|
private javax.swing.JLabel testResultValueLabel;
|
||||||
|
private javax.swing.JTextField testUntranslatedTextField;
|
||||||
|
private javax.swing.JLabel untranslatedLabel;
|
||||||
private javax.swing.JLabel warningLabel;
|
private javax.swing.JLabel warningLabel;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
@ -284,7 +367,7 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||||
String selectedCode = ((GoogleLanguageWrapper) targetLanguageComboBox.getSelectedItem()).getLanguage().getCode();
|
String selectedCode = ((LanguageWrapper) targetLanguageComboBox.getSelectedItem()).getLanguageCode();
|
||||||
if (!StringUtils.isBlank(selectedCode) && !selectedCode.equals(targetLanguageCode)) {
|
if (!StringUtils.isBlank(selectedCode) && !selectedCode.equals(targetLanguageCode)) {
|
||||||
targetLanguageCode = selectedCode;
|
targetLanguageCode = selectedCode;
|
||||||
populateTargetLanguageComboBox();
|
populateTargetLanguageComboBox();
|
||||||
|
@ -21,19 +21,33 @@ package org.sleuthkit.autopsy.texttranslation.translators;
|
|||||||
import com.google.cloud.translate.Language;
|
import com.google.cloud.translate.Language;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for the Language class
|
* Wrapper for Language definitions used by translators
|
||||||
*/
|
*/
|
||||||
class GoogleLanguageWrapper {
|
class LanguageWrapper {
|
||||||
|
|
||||||
private final Language language;
|
private final String languageCode;
|
||||||
|
private final String languageDisplayName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new GoogleLanguageWrapper
|
* Create a new LanguageWrapper to wrap the google language object
|
||||||
*
|
*
|
||||||
* @param lang the Language object to wrap
|
* @param lang the Language object to wrap
|
||||||
*/
|
*/
|
||||||
GoogleLanguageWrapper(Language lang) {
|
LanguageWrapper(Language language) {
|
||||||
language = lang;
|
languageCode = language.getCode();
|
||||||
|
languageDisplayName = language.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new LanguageWrapper to wrap json elements that identify a
|
||||||
|
* language for microsofts translation service
|
||||||
|
*
|
||||||
|
* @param code the code which uniquely identifies a language
|
||||||
|
* @param name the name of the language
|
||||||
|
*/
|
||||||
|
LanguageWrapper(String code, String name) {
|
||||||
|
languageCode = code;
|
||||||
|
languageDisplayName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,14 +55,14 @@ class GoogleLanguageWrapper {
|
|||||||
*
|
*
|
||||||
* @return the wrapped Language
|
* @return the wrapped Language
|
||||||
*/
|
*/
|
||||||
Language getLanguage() {
|
String getLanguageCode() {
|
||||||
return language;
|
return languageCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
//toString overridden so that the jComboBox in the GoogleTranslatorSettingsPanel will display the name of the language
|
//toString overridden so that the jComboBox in the TranslatorSettingsPanels will display the name of the language
|
||||||
return language.getName();
|
return languageDisplayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.texttranslation.translators;
|
||||||
|
|
||||||
|
//import java.io.IOException;
|
||||||
|
//import org.junit.After;
|
||||||
|
//import org.junit.AfterClass;
|
||||||
|
//import org.junit.Before;
|
||||||
|
//import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
//import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for the BingTranslator translation service, these tests have been
|
||||||
|
* commented out because they require credentials to perform
|
||||||
|
*/
|
||||||
|
public class BingTranslatorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTranslate() {
|
||||||
|
// BingTranslator translator = new BingTranslator();
|
||||||
|
// String input = "gato";
|
||||||
|
// String expectedTranslation = "cat";
|
||||||
|
// runTest(translator, input, expectedTranslation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void testQuickStartSentence() throws Exception {
|
||||||
|
// BingTranslator translator = new BingTranslator();
|
||||||
|
// String input = "Willkommen bei Microsoft Translator. Raten Sie mal, wie viele Sprachen ich spreche.";
|
||||||
|
// String expectedTranslation = "Welcome to Microsoft Translator. Guess how many languages I speak.";
|
||||||
|
// runTest(translator, input, expectedTranslation);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testCharacterEscapes() throws Exception {
|
||||||
|
// BingTranslator translator = new BingTranslator();
|
||||||
|
// String input = "\"gato\"";;
|
||||||
|
// String expectedTranslation = "Cat";
|
||||||
|
// runTest(translator, input, expectedTranslation);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testLineBreaks() throws Exception {
|
||||||
|
// BingTranslator translator = new BingTranslator();
|
||||||
|
// String input = "gato\nperro";;
|
||||||
|
// String expectedTranslation = "cat\nDog";
|
||||||
|
// runTest(translator, input, expectedTranslation);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Test whether translator throws an error. This should not be part of our
|
||||||
|
// * regular testing, because we are limited to only 2MB of free translations
|
||||||
|
// * ever.
|
||||||
|
// * @param translator A BingTranslator
|
||||||
|
// * @param input Text to translate
|
||||||
|
// * @param expectedTranslation Not used unless you uncomment those lines.
|
||||||
|
// */
|
||||||
|
// public void runTest(BingTranslator translator, String input, String expectedTranslation) {
|
||||||
|
// String translation;
|
||||||
|
// try {
|
||||||
|
// translation = translator.translate(input);
|
||||||
|
// }
|
||||||
|
// catch (Throwable e) {
|
||||||
|
// fail("Bing translation produced an exception: " + e.getMessage());
|
||||||
|
// return;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// //It's unrealistic to expect the same answer every time, but sometimes
|
||||||
|
// //it's helpful to have this in your debug process.
|
||||||
|
// System.out.println(translation);
|
||||||
|
// assertEquals(expectedTranslation, translation);
|
||||||
|
// */
|
||||||
|
// }
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user